xref: /linux/drivers/hid/hid-sony.c (revision fb705a6dc8e997ea26f0bd93f58c43e2f0592d3a)
1bd28ce00SJiri Slaby /*
2078328daSJiri Kosina  *  HID driver for Sony / PS2 / PS3 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>
11bd28ce00SJiri Slaby  */
12bd28ce00SJiri Slaby 
13bd28ce00SJiri Slaby /*
14bd28ce00SJiri Slaby  * This program is free software; you can redistribute it and/or modify it
15bd28ce00SJiri Slaby  * under the terms of the GNU General Public License as published by the Free
16bd28ce00SJiri Slaby  * Software Foundation; either version 2 of the License, or (at your option)
17bd28ce00SJiri Slaby  * any later version.
18bd28ce00SJiri Slaby  */
19bd28ce00SJiri Slaby 
20ad142b9eSFrank Praznik /*
21ad142b9eSFrank Praznik  * NOTE: in order for the Sony PS3 BD Remote Control to be found by
22078328daSJiri Kosina  * a Bluetooth host, the key combination Start+Enter has to be kept pressed
23078328daSJiri Kosina  * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
24078328daSJiri Kosina  *
25078328daSJiri Kosina  * There will be no PIN request from the device.
26078328daSJiri Kosina  */
27078328daSJiri Kosina 
28bd28ce00SJiri Slaby #include <linux/device.h>
29bd28ce00SJiri Slaby #include <linux/hid.h>
30bd28ce00SJiri Slaby #include <linux/module.h>
315a0e3ad6STejun Heo #include <linux/slab.h>
3240e32ee6SJiri Kosina #include <linux/leds.h>
33d902f472SFrank Praznik #include <linux/power_supply.h>
34d902f472SFrank Praznik #include <linux/spinlock.h>
35d2d782fcSFrank Praznik #include <linux/list.h>
368025087aSFrank Praznik #include <linux/idr.h>
37e5606230SFrank Praznik #include <linux/input/mt.h>
38bd28ce00SJiri Slaby 
39bd28ce00SJiri Slaby #include "hid-ids.h"
40bd28ce00SJiri Slaby 
41f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT       BIT(0)
42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB    BIT(1)
43f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT     BIT(2)
44f1c458caSSven Eckelmann #define BUZZ_CONTROLLER           BIT(3)
45f1c458caSSven Eckelmann #define PS3REMOTE                 BIT(4)
468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
478ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
48cc6e0bbbSJiri Kosina 
49fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
5068330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
5168330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER_BT)
52fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
5368330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER)
54fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
55c8de9dbbSFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
5660781cf4SFrank Praznik 
5760781cf4SFrank Praznik #define MAX_LEDS 4
580a286ef2SSven Eckelmann 
59c607fb8dSAntonio Ospite static __u8 sixaxis_rdesc[] = {
60*fb705a6dSAntonio Ospite 	0x05, 0x01,         /*  Usage Page (Desktop),               */
61*fb705a6dSAntonio Ospite 	0x09, 0x04,         /*  Usage (Joystik),                    */
62*fb705a6dSAntonio Ospite 	0xA1, 0x01,         /*  Collection (Application),           */
63*fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
64*fb705a6dSAntonio Ospite 	0x85, 0x01,         /*          Report ID (1),              */
65*fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
66*fb705a6dSAntonio Ospite 	0x95, 0x01,         /*          Report Count (1),           */
67*fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
68*fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
69*fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
70*fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
71*fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
72*fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
73*fb705a6dSAntonio Ospite 	0x25, 0x01,         /*          Logical Maximum (1),        */
74*fb705a6dSAntonio Ospite 	0x35, 0x00,         /*          Physical Minimum (0),       */
75*fb705a6dSAntonio Ospite 	0x45, 0x01,         /*          Physical Maximum (1),       */
76*fb705a6dSAntonio Ospite 	0x05, 0x09,         /*          Usage Page (Button),        */
77*fb705a6dSAntonio Ospite 	0x19, 0x01,         /*          Usage Minimum (01h),        */
78*fb705a6dSAntonio Ospite 	0x29, 0x13,         /*          Usage Maximum (13h),        */
79*fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
80*fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
81*fb705a6dSAntonio Ospite 	0x95, 0x0D,         /*          Report Count (13),          */
82*fb705a6dSAntonio Ospite 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
83*fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
84*fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
85*fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
86*fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
87*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
88*fb705a6dSAntonio Ospite 	0xA1, 0x00,         /*          Collection (Physical),      */
89*fb705a6dSAntonio Ospite 	0x75, 0x08,         /*              Report Size (8),        */
90*fb705a6dSAntonio Ospite 	0x95, 0x04,         /*              Report Count (4),       */
91*fb705a6dSAntonio Ospite 	0x35, 0x00,         /*              Physical Minimum (0),   */
92*fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
93*fb705a6dSAntonio Ospite 	0x09, 0x30,         /*              Usage (X),              */
94*fb705a6dSAntonio Ospite 	0x09, 0x31,         /*              Usage (Y),              */
95*fb705a6dSAntonio Ospite 	0x09, 0x32,         /*              Usage (Z),              */
96*fb705a6dSAntonio Ospite 	0x09, 0x35,         /*              Usage (Rz),             */
97*fb705a6dSAntonio Ospite 	0x81, 0x02,         /*              Input (Variable),       */
98*fb705a6dSAntonio Ospite 	0xC0,               /*          End Collection,             */
99*fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
100*fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
101*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
102*fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
103*fb705a6dSAntonio Ospite 	0x95, 0x0C,         /*          Report Count (12),          */
104*fb705a6dSAntonio Ospite 	0x81, 0x01,         /*          Input (Constant),           */
105*fb705a6dSAntonio Ospite 	0x75, 0x10,         /*          Report Size (16),           */
106*fb705a6dSAntonio Ospite 	0x95, 0x04,         /*          Report Count (4),           */
107*fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
108*fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
109*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
110*fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
111*fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
112*fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
113*fb705a6dSAntonio Ospite 	0x85, 0x02,         /*          Report ID (2),              */
114*fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
115*fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
116*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
117*fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
118*fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
119*fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
120*fb705a6dSAntonio Ospite 	0x85, 0xEE,         /*          Report ID (238),            */
121*fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
122*fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
123*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
124*fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
125*fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
126*fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
127*fb705a6dSAntonio Ospite 	0x85, 0xEF,         /*          Report ID (239),            */
128*fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
129*fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
130*fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
131*fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
132*fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
133*fb705a6dSAntonio Ospite 	0xC0                /*  End Collection                      */
134e57a67daSMauro Carvalho Chehab };
135e57a67daSMauro Carvalho Chehab 
136ad142b9eSFrank Praznik /*
137ad142b9eSFrank Praznik  * The default descriptor doesn't provide mapping for the accelerometers
13858d7027bSFrank Praznik  * or orientation sensors.  This fixed descriptor maps the accelerometers
13958d7027bSFrank Praznik  * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
14058d7027bSFrank Praznik  * to usage values 0x43, 0x44 and 0x45.
14158d7027bSFrank Praznik  */
142ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = {
14358d7027bSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
14458d7027bSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
14558d7027bSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
14658d7027bSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
14758d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
14858d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
14958d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
15058d7027bSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
15158d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
15258d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
15358d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
15458d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
15558d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
15658d7027bSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
15758d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
15858d7027bSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
15958d7027bSFrank Praznik 	0x35, 0x00,         /*      Physical Minimum (0),           */
16058d7027bSFrank Praznik 	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
16158d7027bSFrank Praznik 	0x65, 0x14,         /*      Unit (Degrees),                 */
16258d7027bSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
16358d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
16458d7027bSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
16558d7027bSFrank Praznik 	0x65, 0x00,         /*      Unit,                           */
16658d7027bSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
16758d7027bSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
16858d7027bSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
16958d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
17058d7027bSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
17158d7027bSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
17258d7027bSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
17358d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
17458d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
17558d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
17658d7027bSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
17758d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
17858d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
17958d7027bSFrank Praznik 	0x25, 0x7F,         /*      Logical Maximum (127),          */
18058d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
18158d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
18258d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
18358d7027bSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
18458d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
18558d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
18658d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
18758d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
18858d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
18958d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
19058d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
19158d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
19258d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
19358d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
19458d7027bSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
19558d7027bSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
19658d7027bSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
19758d7027bSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
19858d7027bSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
19958d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
20058d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
20158d7027bSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
20258d7027bSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
20358d7027bSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
20458d7027bSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
20558d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
20658d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
20758d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
20858d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
20958d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
21058d7027bSFrank Praznik 	0x25, 0xFF,         /*      Logical Maximum (255),          */
21158d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
21258d7027bSFrank Praznik 	0x95, 0x27,         /*      Report Count (39),              */
21358d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
21458d7027bSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
21558d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
21658d7027bSFrank Praznik 	0x95, 0x1F,         /*      Report Count (31),              */
21758d7027bSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
21858d7027bSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
21958d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
22058d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
22158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22258d7027bSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
22358d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
22458d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
22558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22658d7027bSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
22758d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
22858d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
22958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23058d7027bSFrank Praznik 	0x85, 0x10,         /*      Report ID (16),                 */
23158d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
23258d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
23358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23458d7027bSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
23558d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
23658d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
23758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23858d7027bSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
23958d7027bSFrank Praznik 	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
24058d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
24158d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
24258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24358d7027bSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
24458d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
24558d7027bSFrank Praznik 	0x95, 0x16,         /*      Report Count (22),              */
24658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24758d7027bSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
24858d7027bSFrank Praznik 	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
24958d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
25058d7027bSFrank Praznik 	0x95, 0x10,         /*      Report Count (16),              */
25158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25258d7027bSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
25358d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
25458d7027bSFrank Praznik 	0x95, 0x2C,         /*      Report Count (44),              */
25558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25658d7027bSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
25758d7027bSFrank Praznik 	0x85, 0x80,         /*      Report ID (128),                */
25858d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
25958d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
26058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26158d7027bSFrank Praznik 	0x85, 0x81,         /*      Report ID (129),                */
26258d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
26358d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
26458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26558d7027bSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
26658d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
26758d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
26858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26958d7027bSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
27058d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
27158d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
27258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27358d7027bSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
27458d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
27558d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
27658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27758d7027bSFrank Praznik 	0x85, 0x85,         /*      Report ID (133),                */
27858d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
27958d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
28058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28158d7027bSFrank Praznik 	0x85, 0x86,         /*      Report ID (134),                */
28258d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
28358d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
28458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28558d7027bSFrank Praznik 	0x85, 0x87,         /*      Report ID (135),                */
28658d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
28758d7027bSFrank Praznik 	0x95, 0x23,         /*      Report Count (35),              */
28858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28958d7027bSFrank Praznik 	0x85, 0x88,         /*      Report ID (136),                */
29058d7027bSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
29158d7027bSFrank Praznik 	0x95, 0x22,         /*      Report Count (34),              */
29258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29358d7027bSFrank Praznik 	0x85, 0x89,         /*      Report ID (137),                */
29458d7027bSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
29558d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
29658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29758d7027bSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
29858d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
29958d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
30058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30158d7027bSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
30258d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
30358d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
30458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30558d7027bSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
30658d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
30758d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
30858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30958d7027bSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
31058d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
31158d7027bSFrank Praznik 	0x95, 0x0C,         /*      Report Count (12),              */
31258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31358d7027bSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
31458d7027bSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
31558d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
31658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31758d7027bSFrank Praznik 	0x85, 0xA1,         /*      Report ID (161),                */
31858d7027bSFrank Praznik 	0x09, 0x41,         /*      Usage (41h),                    */
31958d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
32058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32158d7027bSFrank Praznik 	0x85, 0xA2,         /*      Report ID (162),                */
32258d7027bSFrank Praznik 	0x09, 0x42,         /*      Usage (42h),                    */
32358d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
32458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32558d7027bSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
32658d7027bSFrank Praznik 	0x09, 0x43,         /*      Usage (43h),                    */
32758d7027bSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
32858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32958d7027bSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
33058d7027bSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
33158d7027bSFrank Praznik 	0x95, 0x0D,         /*      Report Count (13),              */
33258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33358d7027bSFrank Praznik 	0x85, 0xA5,         /*      Report ID (165),                */
33458d7027bSFrank Praznik 	0x09, 0x45,         /*      Usage (45h),                    */
33558d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
33658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33758d7027bSFrank Praznik 	0x85, 0xA6,         /*      Report ID (166),                */
33858d7027bSFrank Praznik 	0x09, 0x46,         /*      Usage (46h),                    */
33958d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
34058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34158d7027bSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
34258d7027bSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
34358d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
34458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34558d7027bSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
34658d7027bSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
34758d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
34858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34958d7027bSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
35058d7027bSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
35158d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
35258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
35358d7027bSFrank Praznik 	0x85, 0xA7,         /*      Report ID (167),                */
35458d7027bSFrank Praznik 	0x09, 0x4A,         /*      Usage (4Ah),                    */
35558d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
35658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
35758d7027bSFrank Praznik 	0x85, 0xA8,         /*      Report ID (168),                */
35858d7027bSFrank Praznik 	0x09, 0x4B,         /*      Usage (4Bh),                    */
35958d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
36058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
36158d7027bSFrank Praznik 	0x85, 0xA9,         /*      Report ID (169),                */
36258d7027bSFrank Praznik 	0x09, 0x4C,         /*      Usage (4Ch),                    */
36358d7027bSFrank Praznik 	0x95, 0x08,         /*      Report Count (8),               */
36458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
36558d7027bSFrank Praznik 	0x85, 0xAA,         /*      Report ID (170),                */
36658d7027bSFrank Praznik 	0x09, 0x4E,         /*      Usage (4Eh),                    */
36758d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
36858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
36958d7027bSFrank Praznik 	0x85, 0xAB,         /*      Report ID (171),                */
37058d7027bSFrank Praznik 	0x09, 0x4F,         /*      Usage (4Fh),                    */
37158d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
37258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
37358d7027bSFrank Praznik 	0x85, 0xAC,         /*      Report ID (172),                */
37458d7027bSFrank Praznik 	0x09, 0x50,         /*      Usage (50h),                    */
37558d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
37658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
37758d7027bSFrank Praznik 	0x85, 0xAD,         /*      Report ID (173),                */
37858d7027bSFrank Praznik 	0x09, 0x51,         /*      Usage (51h),                    */
37958d7027bSFrank Praznik 	0x95, 0x0B,         /*      Report Count (11),              */
38058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38158d7027bSFrank Praznik 	0x85, 0xAE,         /*      Report ID (174),                */
38258d7027bSFrank Praznik 	0x09, 0x52,         /*      Usage (52h),                    */
38358d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
38458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38558d7027bSFrank Praznik 	0x85, 0xAF,         /*      Report ID (175),                */
38658d7027bSFrank Praznik 	0x09, 0x53,         /*      Usage (53h),                    */
38758d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
38858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38958d7027bSFrank Praznik 	0x85, 0xB0,         /*      Report ID (176),                */
39058d7027bSFrank Praznik 	0x09, 0x54,         /*      Usage (54h),                    */
39158d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
39258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
39358d7027bSFrank Praznik 	0xC0                /*  End Collection                      */
394ed19d8cfSFrank Praznik };
395ed19d8cfSFrank Praznik 
396ad142b9eSFrank Praznik /*
397ad142b9eSFrank Praznik  * The default behavior of the Dualshock 4 is to send reports using report
398d829674dSFrank Praznik  * type 1 when running over Bluetooth. However, as soon as it receives a
399d829674dSFrank Praznik  * report of type 17 to set the LEDs or rumble it starts returning it's state
400d829674dSFrank Praznik  * in report 17 instead of 1.  Since report 17 is undefined in the default HID
401d829674dSFrank Praznik  * descriptor the button and axis definitions must be moved to report 17 or
402d829674dSFrank Praznik  * the HID layer won't process the received input once a report is sent.
403d829674dSFrank Praznik  */
404d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = {
405d829674dSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
406d829674dSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
407d829674dSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
408d829674dSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
409d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
410d829674dSFrank Praznik 	0x95, 0x0A,         /*      Report Count (9),               */
411d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
412d829674dSFrank Praznik 	0x06, 0x04, 0xFF,   /*      Usage Page (FF04h),             */
413d829674dSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
414d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
415d829674dSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
416d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
417d829674dSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
418d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
419d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
420d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
421d829674dSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
422d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
423d829674dSFrank Praznik 	0x95, 0x28,         /*      Report Count (40),              */
424d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
425d829674dSFrank Praznik 	0x85, 0x06,         /*      Report ID (6),                  */
426d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
427d829674dSFrank Praznik 	0x95, 0x34,         /*      Report Count (52),              */
428d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
429d829674dSFrank Praznik 	0x85, 0x07,         /*      Report ID (7),                  */
430d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
431d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
432d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
433d829674dSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
434d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
435d829674dSFrank Praznik 	0x95, 0x2F,         /*      Report Count (47),              */
436d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
437d829674dSFrank Praznik 	0x06, 0x03, 0xFF,   /*      Usage Page (FF03h),             */
438d829674dSFrank Praznik 	0x85, 0x03,         /*      Report ID (3),                  */
439d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
440d829674dSFrank Praznik 	0x95, 0x26,         /*      Report Count (38),              */
441d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
442d829674dSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
443d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
444d829674dSFrank Praznik 	0x95, 0x2E,         /*      Report Count (46),              */
445d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
446d829674dSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
447d829674dSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
448d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
449d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
450d829674dSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
451d829674dSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
452d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
453d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
454d829674dSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
455d829674dSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
456d829674dSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
457d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
458d829674dSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
459d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
460d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
461d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
462d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
463d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
464d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
465d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
466d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
467d829674dSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
468d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
469d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
470d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
471d829674dSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
472d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
473d829674dSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
474d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
475d829674dSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
476d829674dSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
477d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
478d829674dSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
479d829674dSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
480d829674dSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
481d829674dSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
482d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
483d829674dSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
484d829674dSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
485d829674dSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
486d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
487d829674dSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
488d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
489d829674dSFrank Praznik 	0x81, 0x01,         /*      Input (Constant),               */
490d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
491d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
492d829674dSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
493d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
494d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
495d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
496d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
497d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
498d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
499d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
500d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
501d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
502d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
503d829674dSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
504d829674dSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
505d829674dSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
506d829674dSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
507d829674dSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
508d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
509d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
510d829674dSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
511d829674dSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
512d829674dSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
513d829674dSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
514d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
515d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
516d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
517d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
518d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
519d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
520d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
521d829674dSFrank Praznik 	0x95, 0x31,         /*      Report Count (51),              */
522d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
523d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
524d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
525d829674dSFrank Praznik 	0x95, 0x4D,         /*      Report Count (77),              */
526d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
527d829674dSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
528d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
529d829674dSFrank Praznik 	0x95, 0x8D,         /*      Report Count (141),             */
530d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
531d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
532d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
533d829674dSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
534d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
535d829674dSFrank Praznik 	0x95, 0xCD,         /*      Report Count (205),             */
536d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
537d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
538d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
539d829674dSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
540d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
541d829674dSFrank Praznik 	0x96, 0x0D, 0x01,   /*      Report Count (269),             */
542d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
543d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
544d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
545d829674dSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
546d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
547d829674dSFrank Praznik 	0x96, 0x4D, 0x01,   /*      Report Count (333),             */
548d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
549d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
550d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
551d829674dSFrank Praznik 	0x85, 0x16,         /*      Report ID (22),                 */
552d829674dSFrank Praznik 	0x09, 0x2A,         /*      Usage (2Ah),                    */
553d829674dSFrank Praznik 	0x96, 0x8D, 0x01,   /*      Report Count (397),             */
554d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
555d829674dSFrank Praznik 	0x09, 0x2B,         /*      Usage (2Bh),                    */
556d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
557d829674dSFrank Praznik 	0x85, 0x17,         /*      Report ID (23),                 */
558d829674dSFrank Praznik 	0x09, 0x2C,         /*      Usage (2Ch),                    */
559d829674dSFrank Praznik 	0x96, 0xCD, 0x01,   /*      Report Count (461),             */
560d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
561d829674dSFrank Praznik 	0x09, 0x2D,         /*      Usage (2Dh),                    */
562d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
563d829674dSFrank Praznik 	0x85, 0x18,         /*      Report ID (24),                 */
564d829674dSFrank Praznik 	0x09, 0x2E,         /*      Usage (2Eh),                    */
565d829674dSFrank Praznik 	0x96, 0x0D, 0x02,   /*      Report Count (525),             */
566d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
567d829674dSFrank Praznik 	0x09, 0x2F,         /*      Usage (2Fh),                    */
568d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
569d829674dSFrank Praznik 	0x85, 0x19,         /*      Report ID (25),                 */
570d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
571d829674dSFrank Praznik 	0x96, 0x22, 0x02,   /*      Report Count (546),             */
572d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
573d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
574d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
575d829674dSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
576d829674dSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
577d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
578d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
579d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
580d829674dSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
581d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
582d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
583d829674dSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
584d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
585d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
586d829674dSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
587d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
588d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
589d829674dSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
590d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
591d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
592d829674dSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
593d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
594d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
595d829674dSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
596d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
597d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
598d829674dSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
599d829674dSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
600d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
601d829674dSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
602d829674dSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
603d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
604d829674dSFrank Praznik 	0xC0                /*  End Collection                      */
605d829674dSFrank Praznik };
606d829674dSFrank Praznik 
607078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
608078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
609078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
610078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
611078328daSJiri Kosina 
612078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
613078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
614078328daSJiri Kosina 
615078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
616078328daSJiri Kosina 	   * number but it's not needed for correct operation */
617078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
618078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
619078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
620078328daSJiri Kosina 
621078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
622078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
623078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
624078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
625078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
626078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
627078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
628078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
629078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
630078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
631078328daSJiri Kosina 
632078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
633078328daSJiri Kosina 
634078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
635078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
636078328daSJiri Kosina 
637078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
638078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
639078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
640078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
641078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
642078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
643078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
644078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
645078328daSJiri Kosina 	  0x80,              /* MInput  */
646078328daSJiri Kosina 
647078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
648078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
649078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
650078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
651078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
652078328daSJiri Kosina 
653078328daSJiri Kosina 	  /* 12th byte is for battery strength */
654078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
655078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
656078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
657078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
658078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
659078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
660078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
661078328daSJiri Kosina 
662078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
663078328daSJiri Kosina 
664078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
665078328daSJiri Kosina };
666078328daSJiri Kosina 
667078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
668078328daSJiri Kosina 	[0x01] = KEY_SELECT,
669078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
670078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
671078328daSJiri Kosina 	[0x04] = BTN_START,
672078328daSJiri Kosina 	[0x05] = KEY_UP,
673078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
674078328daSJiri Kosina 	[0x07] = KEY_DOWN,
675078328daSJiri Kosina 	[0x08] = KEY_LEFT,
676078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
677078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
678078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
679078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
680078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
681078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
682078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
683078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
684078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
685078328daSJiri Kosina 	[0x14] = KEY_ENTER,
686078328daSJiri Kosina };
687078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
688078328daSJiri Kosina 	[0x00] = KEY_1,
689078328daSJiri Kosina 	[0x01] = KEY_2,
690078328daSJiri Kosina 	[0x02] = KEY_3,
691078328daSJiri Kosina 	[0x03] = KEY_4,
692078328daSJiri Kosina 	[0x04] = KEY_5,
693078328daSJiri Kosina 	[0x05] = KEY_6,
694078328daSJiri Kosina 	[0x06] = KEY_7,
695078328daSJiri Kosina 	[0x07] = KEY_8,
696078328daSJiri Kosina 	[0x08] = KEY_9,
697078328daSJiri Kosina 	[0x09] = KEY_0,
698078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
699078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
700078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
701078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
702078328daSJiri Kosina 	[0x28] = KEY_TIME,
703078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
704078328daSJiri Kosina 	[0x31] = KEY_NEXT,
705078328daSJiri Kosina 	[0x32] = KEY_PLAY,
706078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
707078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
708078328daSJiri Kosina 	[0x38] = KEY_STOP,
709078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
710078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
711078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
712078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
713078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
714078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
715078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
716078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
717078328daSJiri Kosina 	[0x80] = KEY_BLUE,
718078328daSJiri Kosina 	[0x81] = KEY_RED,
719078328daSJiri Kosina 	[0x82] = KEY_GREEN,
720078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
721078328daSJiri Kosina };
722078328daSJiri Kosina 
723f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
724ad142b9eSFrank Praznik 	/*
725ad142b9eSFrank Praznik 	 * The controller has 4 remote buzzers, each with one LED and 5
726f04d5140SColin Leitner 	 * buttons.
727f04d5140SColin Leitner 	 *
728f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
729f04d5140SColin Leitner 	 *
730f04d5140SColin Leitner 	 * Key          Offset
731f04d5140SColin Leitner 	 * -------------------
732f04d5140SColin Leitner 	 * Buzz              1
733f04d5140SColin Leitner 	 * Blue              5
734f04d5140SColin Leitner 	 * Orange            4
735f04d5140SColin Leitner 	 * Green             3
736f04d5140SColin Leitner 	 * Yellow            2
737f04d5140SColin Leitner 	 *
738f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
739f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
740f04d5140SColin Leitner 	 */
741f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
742f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
743f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
744f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
745f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
746f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
747f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
748f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
749f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
750f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
751f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
752f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
753f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
754f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
755f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
756f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
757f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
758f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
759f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
760f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
761f04d5140SColin Leitner };
762f04d5140SColin Leitner 
763d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = {
764d902f472SFrank Praznik 	POWER_SUPPLY_PROP_PRESENT,
765d902f472SFrank Praznik 	POWER_SUPPLY_PROP_CAPACITY,
766d902f472SFrank Praznik 	POWER_SUPPLY_PROP_SCOPE,
767d902f472SFrank Praznik 	POWER_SUPPLY_PROP_STATUS,
768d902f472SFrank Praznik };
769d902f472SFrank Praznik 
77055d3b664SFrank Praznik struct sixaxis_led {
77155d3b664SFrank Praznik 	__u8 time_enabled; /* the total time the led is active (0xff means forever) */
77255d3b664SFrank Praznik 	__u8 duty_length;  /* how long a cycle is in deciseconds (0 means "really fast") */
77355d3b664SFrank Praznik 	__u8 enabled;
77455d3b664SFrank Praznik 	__u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
77555d3b664SFrank Praznik 	__u8 duty_on;  /* % of duty_length the led is on (0xff mean 100%) */
77655d3b664SFrank Praznik } __packed;
77755d3b664SFrank Praznik 
77855d3b664SFrank Praznik struct sixaxis_rumble {
77955d3b664SFrank Praznik 	__u8 padding;
78055d3b664SFrank Praznik 	__u8 right_duration; /* Right motor duration (0xff means forever) */
78155d3b664SFrank Praznik 	__u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
78255d3b664SFrank Praznik 	__u8 left_duration;    /* Left motor duration (0xff means forever) */
78355d3b664SFrank Praznik 	__u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
78455d3b664SFrank Praznik } __packed;
78555d3b664SFrank Praznik 
78655d3b664SFrank Praznik struct sixaxis_output_report {
78755d3b664SFrank Praznik 	__u8 report_id;
78855d3b664SFrank Praznik 	struct sixaxis_rumble rumble;
78955d3b664SFrank Praznik 	__u8 padding[4];
79055d3b664SFrank Praznik 	__u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
79155d3b664SFrank Praznik 	struct sixaxis_led led[4];    /* LEDx at (4 - x) */
79255d3b664SFrank Praznik 	struct sixaxis_led _reserved; /* LED5, not actually soldered */
79355d3b664SFrank Praznik } __packed;
79455d3b664SFrank Praznik 
79555d3b664SFrank Praznik union sixaxis_output_report_01 {
79655d3b664SFrank Praznik 	struct sixaxis_output_report data;
79755d3b664SFrank Praznik 	__u8 buf[36];
79855d3b664SFrank Praznik };
79955d3b664SFrank Praznik 
800d2d782fcSFrank Praznik static spinlock_t sony_dev_list_lock;
801d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list);
8028025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator);
803d2d782fcSFrank Praznik 
804cc6e0bbbSJiri Kosina struct sony_sc {
805d902f472SFrank Praznik 	spinlock_t lock;
806d2d782fcSFrank Praznik 	struct list_head list_node;
8070a286ef2SSven Eckelmann 	struct hid_device *hdev;
80860781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
809cc6e0bbbSJiri Kosina 	unsigned long quirks;
8100a286ef2SSven Eckelmann 	struct work_struct state_worker;
811d902f472SFrank Praznik 	struct power_supply battery;
8128025087aSFrank Praznik 	int device_id;
813f04d5140SColin Leitner 
8149f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
8159f323b68SSven Eckelmann 	__u8 left;
8169f323b68SSven Eckelmann 	__u8 right;
8179f323b68SSven Eckelmann #endif
8189f323b68SSven Eckelmann 
819d2d782fcSFrank Praznik 	__u8 mac_address[6];
8205f5750d2SFrank Praznik 	__u8 worker_initialized;
821d902f472SFrank Praznik 	__u8 cable_state;
822d902f472SFrank Praznik 	__u8 battery_charging;
823d902f472SFrank Praznik 	__u8 battery_capacity;
82460781cf4SFrank Praznik 	__u8 led_state[MAX_LEDS];
825b3ed458cSFrank Praznik 	__u8 led_delay_on[MAX_LEDS];
826b3ed458cSFrank Praznik 	__u8 led_delay_off[MAX_LEDS];
82760781cf4SFrank Praznik 	__u8 led_count;
828cc6e0bbbSJiri Kosina };
829cc6e0bbbSJiri Kosina 
830c607fb8dSAntonio Ospite static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
831c607fb8dSAntonio Ospite 			     unsigned int *rsize)
832c607fb8dSAntonio Ospite {
833c607fb8dSAntonio Ospite 	*rsize = sizeof(sixaxis_rdesc);
834c607fb8dSAntonio Ospite 	return sixaxis_rdesc;
835c607fb8dSAntonio Ospite }
836c607fb8dSAntonio Ospite 
837078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
838078328daSJiri Kosina 			     unsigned int *rsize)
839078328daSJiri Kosina {
840078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
841078328daSJiri Kosina 	return ps3remote_rdesc;
842078328daSJiri Kosina }
843078328daSJiri Kosina 
844078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
845078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
846078328daSJiri Kosina 			     unsigned long **bit, int *max)
847078328daSJiri Kosina {
848078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
849078328daSJiri Kosina 
850078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
851078328daSJiri Kosina 		return -1;
852078328daSJiri Kosina 
853078328daSJiri Kosina 	switch (usage->collection_index) {
854078328daSJiri Kosina 	case 1:
855078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
856078328daSJiri Kosina 			return -1;
857078328daSJiri Kosina 
858078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
859078328daSJiri Kosina 		if (!key)
860078328daSJiri Kosina 			return -1;
861078328daSJiri Kosina 		break;
862078328daSJiri Kosina 	case 2:
863078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
864078328daSJiri Kosina 			return -1;
865078328daSJiri Kosina 
866078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
867078328daSJiri Kosina 		if (!key)
868078328daSJiri Kosina 			return -1;
869078328daSJiri Kosina 		break;
870078328daSJiri Kosina 	default:
871078328daSJiri Kosina 		return -1;
872078328daSJiri Kosina 	}
873078328daSJiri Kosina 
874078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
875078328daSJiri Kosina 	return 1;
876078328daSJiri Kosina }
877078328daSJiri Kosina 
878078328daSJiri Kosina 
879cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
88073e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
88173e4008dSNikolai Kondrashov 		unsigned int *rsize)
882cc6e0bbbSJiri Kosina {
883cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
884cc6e0bbbSJiri Kosina 
88599d24902SFernando Luis Vázquez Cao 	/*
88699d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
88799d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
88899d24902SFernando Luis Vázquez Cao 	 */
88999d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
89099d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
89199d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
89299d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
89399d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
89499d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
89599d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
896a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
89799d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
898cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
899cc6e0bbbSJiri Kosina 	}
90061ab44beSSimon Wood 
901ed19d8cfSFrank Praznik 	/*
902ed19d8cfSFrank Praznik 	 * The default Dualshock 4 USB descriptor doesn't assign
903ed19d8cfSFrank Praznik 	 * the gyroscope values to corresponding axes so we need a
904ed19d8cfSFrank Praznik 	 * modified one.
905ed19d8cfSFrank Praznik 	 */
906ed19d8cfSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
907ed19d8cfSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
908ed19d8cfSFrank Praznik 		rdesc = dualshock4_usb_rdesc;
909ed19d8cfSFrank Praznik 		*rsize = sizeof(dualshock4_usb_rdesc);
910d829674dSFrank Praznik 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
911d829674dSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
912d829674dSFrank Praznik 		rdesc = dualshock4_bt_rdesc;
913d829674dSFrank Praznik 		*rsize = sizeof(dualshock4_bt_rdesc);
914ed19d8cfSFrank Praznik 	}
915ed19d8cfSFrank Praznik 
916c607fb8dSAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER)
917c607fb8dSAntonio Ospite 		return sixaxis_fixup(hdev, rdesc, rsize);
918078328daSJiri Kosina 
919078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
920078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
921078328daSJiri Kosina 
92273e4008dSNikolai Kondrashov 	return rdesc;
923cc6e0bbbSJiri Kosina }
924cc6e0bbbSJiri Kosina 
925d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
926d902f472SFrank Praznik {
927d902f472SFrank Praznik 	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
928d902f472SFrank Praznik 	unsigned long flags;
929d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
930d902f472SFrank Praznik 
931ad142b9eSFrank Praznik 	/*
932ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
933d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
934d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
935d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
936d902f472SFrank Praznik 	 */
937d902f472SFrank Praznik 	if (rd[30] >= 0xee) {
938d902f472SFrank Praznik 		battery_capacity = 100;
939a43e94a3SFrank Praznik 		battery_charging = !(rd[30] & 0x01);
940d902f472SFrank Praznik 	} else {
941ac3c9a94SFrank Praznik 		__u8 index = rd[30] <= 5 ? rd[30] : 5;
942ac3c9a94SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[index];
943d902f472SFrank Praznik 		battery_charging = 0;
944d902f472SFrank Praznik 	}
945914c5783SFrank Praznik 	cable_state = !(rd[31] & 0x04);
946d902f472SFrank Praznik 
947d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
948d902f472SFrank Praznik 	sc->cable_state = cable_state;
949d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
950d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
951d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
952d902f472SFrank Praznik }
953d902f472SFrank Praznik 
954d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
955d902f472SFrank Praznik {
956e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
957e5606230SFrank Praznik 						struct hid_input, list);
958e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
959d902f472SFrank Praznik 	unsigned long flags;
9606c5f860dSFrank Praznik 	int n, offset;
961d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
962d902f472SFrank Praznik 
963ad142b9eSFrank Praznik 	/*
964ad142b9eSFrank Praznik 	 * Battery and touchpad data starts at byte 30 in the USB report and
9656c5f860dSFrank Praznik 	 * 32 in Bluetooth report.
9666c5f860dSFrank Praznik 	 */
9676c5f860dSFrank Praznik 	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
9686c5f860dSFrank Praznik 
969ad142b9eSFrank Praznik 	/*
970ad142b9eSFrank Praznik 	 * The lower 4 bits of byte 30 contain the battery level
971d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
972d902f472SFrank Praznik 	 */
9736c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
9746c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
975d902f472SFrank Praznik 
976ad142b9eSFrank Praznik 	/*
977ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
9786c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
9796c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
980d902f472SFrank Praznik 	 */
9816c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
982d902f472SFrank Praznik 		battery_charging = 0;
983d902f472SFrank Praznik 	else
984d902f472SFrank Praznik 		battery_charging = 1;
985d902f472SFrank Praznik 
9866c5f860dSFrank Praznik 	if (!cable_state)
9876c5f860dSFrank Praznik 		battery_capacity++;
988d902f472SFrank Praznik 	if (battery_capacity > 10)
9896c5f860dSFrank Praznik 		battery_capacity = 10;
9906c5f860dSFrank Praznik 
991d902f472SFrank Praznik 	battery_capacity *= 10;
992d902f472SFrank Praznik 
993d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
994d902f472SFrank Praznik 	sc->cable_state = cable_state;
995d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
996d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
997d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
998e5606230SFrank Praznik 
9996c5f860dSFrank Praznik 	offset += 5;
10006c5f860dSFrank Praznik 
1001ad142b9eSFrank Praznik 	/*
1002ad142b9eSFrank Praznik 	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
10036c5f860dSFrank Praznik 	 * and 37 on Bluetooth.
1004e5606230SFrank Praznik 	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
1005e5606230SFrank Praznik 	 * indicator that is 0 when pressed and 1 when not pressed.
1006e5606230SFrank Praznik 	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
1007e5606230SFrank Praznik 	 * The data for the second touch is in the same format and immediatly
1008e5606230SFrank Praznik 	 * follows the data for the first.
1009e5606230SFrank Praznik 	 */
1010e5606230SFrank Praznik 	for (n = 0; n < 2; n++) {
1011e5606230SFrank Praznik 		__u16 x, y;
1012e5606230SFrank Praznik 
1013e5606230SFrank Praznik 		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
1014e5606230SFrank Praznik 		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
1015e5606230SFrank Praznik 
1016e5606230SFrank Praznik 		input_mt_slot(input_dev, n);
1017e5606230SFrank Praznik 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
1018e5606230SFrank Praznik 					!(rd[offset] >> 7));
1019e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
1020e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
1021e5606230SFrank Praznik 
1022e5606230SFrank Praznik 		offset += 4;
1023e5606230SFrank Praznik 	}
1024d902f472SFrank Praznik }
1025d902f472SFrank Praznik 
1026c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
1027c9e4d877SSimon Wood 		__u8 *rd, int size)
1028c9e4d877SSimon Wood {
1029c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
1030c9e4d877SSimon Wood 
1031ad142b9eSFrank Praznik 	/*
1032ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
1033c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
1034c9e4d877SSimon Wood 	 */
1035fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
1036c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
1037c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
1038c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
1039c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
1040d902f472SFrank Praznik 
1041d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
104268330d83SFrank Praznik 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
104368330d83SFrank Praznik 			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
104468330d83SFrank Praznik 			&& rd[0] == 0x11 && size == 78)) {
1045d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
1046c9e4d877SSimon Wood 	}
1047c9e4d877SSimon Wood 
1048c9e4d877SSimon Wood 	return 0;
1049c9e4d877SSimon Wood }
1050c9e4d877SSimon Wood 
1051f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
1052f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
1053f04d5140SColin Leitner 			unsigned long **bit, int *max)
1054f04d5140SColin Leitner {
1055f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1056f04d5140SColin Leitner 
1057f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
1058f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
1059f04d5140SColin Leitner 
1060f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
1061f04d5140SColin Leitner 			return -1;
1062f04d5140SColin Leitner 
1063f04d5140SColin Leitner 		switch (usage->collection_index) {
1064f04d5140SColin Leitner 		case 1:
1065f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
1066f04d5140SColin Leitner 				return -1;
1067f04d5140SColin Leitner 
1068f04d5140SColin Leitner 			key = buzz_keymap[key];
1069f04d5140SColin Leitner 			if (!key)
1070f04d5140SColin Leitner 				return -1;
1071f04d5140SColin Leitner 			break;
1072f04d5140SColin Leitner 		default:
1073f04d5140SColin Leitner 			return -1;
1074f04d5140SColin Leitner 		}
1075f04d5140SColin Leitner 
1076f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1077f04d5140SColin Leitner 		return 1;
1078f04d5140SColin Leitner 	}
1079f04d5140SColin Leitner 
1080078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1081078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
1082078328daSJiri Kosina 
10836f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
10846f498018SBenjamin Tissoires 	return 0;
1085f04d5140SColin Leitner }
1086f04d5140SColin Leitner 
10875710fabfSAntonio Ospite /*
1088bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1089bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1090bd28ce00SJiri Slaby  * events.
1091bd28ce00SJiri Slaby  */
1092816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1093bd28ce00SJiri Slaby {
1094bd28ce00SJiri Slaby 	int ret;
1095bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
1096bd28ce00SJiri Slaby 
1097bd28ce00SJiri Slaby 	if (!buf)
1098bd28ce00SJiri Slaby 		return -ENOMEM;
1099bd28ce00SJiri Slaby 
1100cafebc05SBenjamin Tissoires 	ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
1101cafebc05SBenjamin Tissoires 				 HID_REQ_GET_REPORT);
1102f204828aSBenjamin Tissoires 
1103bd28ce00SJiri Slaby 	if (ret < 0)
11044291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
1105bd28ce00SJiri Slaby 
1106bd28ce00SJiri Slaby 	kfree(buf);
1107bd28ce00SJiri Slaby 
1108bd28ce00SJiri Slaby 	return ret;
1109bd28ce00SJiri Slaby }
1110bd28ce00SJiri Slaby 
1111816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1112f9ce7c28SBastien Nocera {
1113fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
1114b0dd72aaSBenjamin Tissoires 	return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
1115b0dd72aaSBenjamin Tissoires 				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
1116f9ce7c28SBastien Nocera }
1117f9ce7c28SBastien Nocera 
1118ad142b9eSFrank Praznik /*
1119ad142b9eSFrank Praznik  * Requesting feature report 0x02 in Bluetooth mode changes the state of the
112068330d83SFrank Praznik  * controller so that it sends full input reports of type 0x11.
112168330d83SFrank Praznik  */
112268330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev)
112368330d83SFrank Praznik {
112468330d83SFrank Praznik 	__u8 buf[37] = { 0 };
112568330d83SFrank Praznik 
112668330d83SFrank Praznik 	return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),
112768330d83SFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1128bd28ce00SJiri Slaby }
1129bd28ce00SJiri Slaby 
11308025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS])
11318025087aSFrank Praznik {
11328025087aSFrank Praznik 	static const __u8 sixaxis_leds[10][4] = {
11338025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x00 },
11348025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x00 },
11358025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x00 },
11368025087aSFrank Praznik 				{ 0x00, 0x00, 0x00, 0x01 },
11378025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x01 },
11388025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x01 },
11398025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x01 },
11408025087aSFrank Praznik 				{ 0x01, 0x00, 0x01, 0x01 },
11418025087aSFrank Praznik 				{ 0x00, 0x01, 0x01, 0x01 },
11428025087aSFrank Praznik 				{ 0x01, 0x01, 0x01, 0x01 }
11438025087aSFrank Praznik 	};
11448025087aSFrank Praznik 
11458025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
11468025087aSFrank Praznik 
11478025087aSFrank Praznik 	if (id < 0)
11488025087aSFrank Praznik 		return;
11498025087aSFrank Praznik 
11508025087aSFrank Praznik 	id %= 10;
11518025087aSFrank Praznik 	memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
11528025087aSFrank Praznik }
11538025087aSFrank Praznik 
11548025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS])
11558025087aSFrank Praznik {
11568025087aSFrank Praznik 	/* The first 4 color/index entries match what the PS4 assigns */
11578025087aSFrank Praznik 	static const __u8 color_code[7][3] = {
11588025087aSFrank Praznik 			/* Blue   */	{ 0x00, 0x00, 0x01 },
11598025087aSFrank Praznik 			/* Red	  */	{ 0x01, 0x00, 0x00 },
11608025087aSFrank Praznik 			/* Green  */	{ 0x00, 0x01, 0x00 },
11618025087aSFrank Praznik 			/* Pink   */	{ 0x02, 0x00, 0x01 },
11628025087aSFrank Praznik 			/* Orange */	{ 0x02, 0x01, 0x00 },
11638025087aSFrank Praznik 			/* Teal   */	{ 0x00, 0x01, 0x01 },
11648025087aSFrank Praznik 			/* White  */	{ 0x01, 0x01, 0x01 }
11658025087aSFrank Praznik 	};
11668025087aSFrank Praznik 
11678025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
11688025087aSFrank Praznik 
11698025087aSFrank Praznik 	if (id < 0)
11708025087aSFrank Praznik 		return;
11718025087aSFrank Praznik 
11728025087aSFrank Praznik 	id %= 7;
11738025087aSFrank Praznik 	memcpy(values, color_code[id], sizeof(color_code[id]));
11748025087aSFrank Praznik }
11758025087aSFrank Praznik 
117660781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
1177f04d5140SColin Leitner {
1178f04d5140SColin Leitner 	struct list_head *report_list =
1179f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1180f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1181f04d5140SColin Leitner 		struct hid_report, list);
1182f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
1183f04d5140SColin Leitner 
1184f04d5140SColin Leitner 	value[0] = 0x00;
118560781cf4SFrank Praznik 	value[1] = leds[0] ? 0xff : 0x00;
118660781cf4SFrank Praznik 	value[2] = leds[1] ? 0xff : 0x00;
118760781cf4SFrank Praznik 	value[3] = leds[2] ? 0xff : 0x00;
118860781cf4SFrank Praznik 	value[4] = leds[3] ? 0xff : 0x00;
1189f04d5140SColin Leitner 	value[5] = 0x00;
1190f04d5140SColin Leitner 	value[6] = 0x00;
1191f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1192f04d5140SColin Leitner }
1193f04d5140SColin Leitner 
1194fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count)
11950a286ef2SSven Eckelmann {
119660781cf4SFrank Praznik 	int n;
11970a286ef2SSven Eckelmann 
119860781cf4SFrank Praznik 	BUG_ON(count > MAX_LEDS);
119960781cf4SFrank Praznik 
1200fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER && count == 4) {
1201fa57a810SFrank Praznik 		buzz_set_leds(sc->hdev, leds);
1202fee4e2d5SFrank Praznik 	} else {
120360781cf4SFrank Praznik 		for (n = 0; n < count; n++)
1204fa57a810SFrank Praznik 			sc->led_state[n] = leds[n];
1205fa57a810SFrank Praznik 		schedule_work(&sc->state_worker);
12060a286ef2SSven Eckelmann 	}
12070a286ef2SSven Eckelmann }
12080a286ef2SSven Eckelmann 
1209c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1210f04d5140SColin Leitner 				    enum led_brightness value)
1211f04d5140SColin Leitner {
1212f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1213f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1214f04d5140SColin Leitner 	struct sony_sc *drv_data;
1215f04d5140SColin Leitner 
1216f04d5140SColin Leitner 	int n;
1217b3ed458cSFrank Praznik 	int force_update;
1218f04d5140SColin Leitner 
1219f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12202251b85fSSven Eckelmann 	if (!drv_data) {
1221f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1222f04d5140SColin Leitner 		return;
1223f04d5140SColin Leitner 	}
1224f04d5140SColin Leitner 
1225b3ed458cSFrank Praznik 	/*
1226b3ed458cSFrank Praznik 	 * The Sixaxis on USB will override any LED settings sent to it
1227b3ed458cSFrank Praznik 	 * and keep flashing all of the LEDs until the PS button is pressed.
1228b3ed458cSFrank Praznik 	 * Updates, even if redundant, must be always be sent to the
1229b3ed458cSFrank Praznik 	 * controller to avoid having to toggle the state of an LED just to
1230b3ed458cSFrank Praznik 	 * stop the flashing later on.
1231b3ed458cSFrank Praznik 	 */
1232b3ed458cSFrank Praznik 	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1233b3ed458cSFrank Praznik 
123460781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1235b3ed458cSFrank Praznik 		if (led == drv_data->leds[n] && (force_update ||
1236b3ed458cSFrank Praznik 			(value != drv_data->led_state[n] ||
1237b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] ||
1238b3ed458cSFrank Praznik 			drv_data->led_delay_off[n]))) {
1239b3ed458cSFrank Praznik 
124060781cf4SFrank Praznik 			drv_data->led_state[n] = value;
1241b3ed458cSFrank Praznik 
1242b3ed458cSFrank Praznik 			/* Setting the brightness stops the blinking */
1243b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] = 0;
1244b3ed458cSFrank Praznik 			drv_data->led_delay_off[n] = 0;
1245b3ed458cSFrank Praznik 
1246fa57a810SFrank Praznik 			sony_set_leds(drv_data, drv_data->led_state,
1247fa57a810SFrank Praznik 					drv_data->led_count);
1248f04d5140SColin Leitner 			break;
1249f04d5140SColin Leitner 		}
1250f04d5140SColin Leitner 	}
1251f04d5140SColin Leitner }
1252f04d5140SColin Leitner 
1253c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1254f04d5140SColin Leitner {
1255f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1256f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1257f04d5140SColin Leitner 	struct sony_sc *drv_data;
1258f04d5140SColin Leitner 
1259f04d5140SColin Leitner 	int n;
1260f04d5140SColin Leitner 
1261f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12622251b85fSSven Eckelmann 	if (!drv_data) {
1263f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1264f04d5140SColin Leitner 		return LED_OFF;
1265f04d5140SColin Leitner 	}
1266f04d5140SColin Leitner 
126760781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
12687db7504aSSimon Wood 		if (led == drv_data->leds[n])
12697db7504aSSimon Wood 			return drv_data->led_state[n];
1270f04d5140SColin Leitner 	}
1271f04d5140SColin Leitner 
12727db7504aSSimon Wood 	return LED_OFF;
1273f04d5140SColin Leitner }
1274f04d5140SColin Leitner 
1275b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1276b3ed458cSFrank Praznik 				unsigned long *delay_off)
1277b3ed458cSFrank Praznik {
1278b3ed458cSFrank Praznik 	struct device *dev = led->dev->parent;
1279b3ed458cSFrank Praznik 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1280b3ed458cSFrank Praznik 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
1281b3ed458cSFrank Praznik 	int n;
1282b3ed458cSFrank Praznik 	__u8 new_on, new_off;
1283b3ed458cSFrank Praznik 
1284b3ed458cSFrank Praznik 	if (!drv_data) {
1285b3ed458cSFrank Praznik 		hid_err(hdev, "No device data\n");
1286b3ed458cSFrank Praznik 		return -EINVAL;
1287b3ed458cSFrank Praznik 	}
1288b3ed458cSFrank Praznik 
1289b3ed458cSFrank Praznik 	/* Max delay is 255 deciseconds or 2550 milliseconds */
1290b3ed458cSFrank Praznik 	if (*delay_on > 2550)
1291b3ed458cSFrank Praznik 		*delay_on = 2550;
1292b3ed458cSFrank Praznik 	if (*delay_off > 2550)
1293b3ed458cSFrank Praznik 		*delay_off = 2550;
1294b3ed458cSFrank Praznik 
1295b3ed458cSFrank Praznik 	/* Blink at 1 Hz if both values are zero */
1296b3ed458cSFrank Praznik 	if (!*delay_on && !*delay_off)
1297b3ed458cSFrank Praznik 		*delay_on = *delay_off = 500;
1298b3ed458cSFrank Praznik 
1299b3ed458cSFrank Praznik 	new_on = *delay_on / 10;
1300b3ed458cSFrank Praznik 	new_off = *delay_off / 10;
1301b3ed458cSFrank Praznik 
1302b3ed458cSFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1303b3ed458cSFrank Praznik 		if (led == drv_data->leds[n])
1304b3ed458cSFrank Praznik 			break;
1305b3ed458cSFrank Praznik 	}
1306b3ed458cSFrank Praznik 
1307b3ed458cSFrank Praznik 	/* This LED is not registered on this device */
1308b3ed458cSFrank Praznik 	if (n >= drv_data->led_count)
1309b3ed458cSFrank Praznik 		return -EINVAL;
1310b3ed458cSFrank Praznik 
1311b3ed458cSFrank Praznik 	/* Don't schedule work if the values didn't change */
1312b3ed458cSFrank Praznik 	if (new_on != drv_data->led_delay_on[n] ||
1313b3ed458cSFrank Praznik 		new_off != drv_data->led_delay_off[n]) {
1314b3ed458cSFrank Praznik 		drv_data->led_delay_on[n] = new_on;
1315b3ed458cSFrank Praznik 		drv_data->led_delay_off[n] = new_off;
1316b3ed458cSFrank Praznik 		schedule_work(&drv_data->state_worker);
1317b3ed458cSFrank Praznik 	}
1318b3ed458cSFrank Praznik 
1319b3ed458cSFrank Praznik 	return 0;
1320b3ed458cSFrank Praznik }
1321b3ed458cSFrank Praznik 
1322fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc)
13230a286ef2SSven Eckelmann {
13240a286ef2SSven Eckelmann 	struct led_classdev *led;
13250a286ef2SSven Eckelmann 	int n;
13260a286ef2SSven Eckelmann 
1327fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
13280a286ef2SSven Eckelmann 
1329fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
1330fa57a810SFrank Praznik 		led = sc->leds[n];
1331fa57a810SFrank Praznik 		sc->leds[n] = NULL;
13320a286ef2SSven Eckelmann 		if (!led)
13330a286ef2SSven Eckelmann 			continue;
13340a286ef2SSven Eckelmann 		led_classdev_unregister(led);
13350a286ef2SSven Eckelmann 		kfree(led);
13360a286ef2SSven Eckelmann 	}
133760781cf4SFrank Praznik 
1338fa57a810SFrank Praznik 	sc->led_count = 0;
13390a286ef2SSven Eckelmann }
13400a286ef2SSven Eckelmann 
1341fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc)
1342f04d5140SColin Leitner {
1343fa57a810SFrank Praznik 	struct hid_device *hdev = sc->hdev;
134440e32ee6SJiri Kosina 	int n, ret = 0;
1345b3ed458cSFrank Praznik 	int use_ds4_names;
134640e32ee6SJiri Kosina 	struct led_classdev *led;
134740e32ee6SJiri Kosina 	size_t name_sz;
134840e32ee6SJiri Kosina 	char *name;
13490a286ef2SSven Eckelmann 	size_t name_len;
13500a286ef2SSven Eckelmann 	const char *name_fmt;
1351b3ed458cSFrank Praznik 	static const char * const ds4_name_str[] = { "red", "green", "blue",
1352b3ed458cSFrank Praznik 						  "global" };
13538025087aSFrank Praznik 	__u8 initial_values[MAX_LEDS] = { 0 };
1354b3ed458cSFrank Praznik 	__u8 max_brightness[MAX_LEDS] = { 1 };
1355b3ed458cSFrank Praznik 	__u8 use_hw_blink[MAX_LEDS] = { 0 };
1356f04d5140SColin Leitner 
1357fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1358f04d5140SColin Leitner 
1359fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER) {
1360fa57a810SFrank Praznik 		sc->led_count = 4;
1361b3ed458cSFrank Praznik 		use_ds4_names = 0;
13620a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
13630a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
13649446edb9SKees Cook 		/* Validate expected report characteristics. */
13659446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
13669446edb9SKees Cook 			return -ENODEV;
1367fa57a810SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
13688025087aSFrank Praznik 		dualshock4_set_leds_from_id(sc->device_id, initial_values);
1369b3ed458cSFrank Praznik 		initial_values[3] = 1;
1370b3ed458cSFrank Praznik 		sc->led_count = 4;
1371b3ed458cSFrank Praznik 		memset(max_brightness, 255, 3);
1372b3ed458cSFrank Praznik 		use_hw_blink[3] = 1;
1373b3ed458cSFrank Praznik 		use_ds4_names = 1;
137461ebca93SFrank Praznik 		name_len = 0;
137561ebca93SFrank Praznik 		name_fmt = "%s:%s";
137660781cf4SFrank Praznik 	} else {
13778025087aSFrank Praznik 		sixaxis_set_leds_from_id(sc->device_id, initial_values);
1378fa57a810SFrank Praznik 		sc->led_count = 4;
1379b3ed458cSFrank Praznik 		memset(use_hw_blink, 1, 4);
1380b3ed458cSFrank Praznik 		use_ds4_names = 0;
138161ebca93SFrank Praznik 		name_len = strlen("::sony#");
138261ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
138360781cf4SFrank Praznik 	}
138460781cf4SFrank Praznik 
1385ad142b9eSFrank Praznik 	/*
1386ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1387f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1388ad142b9eSFrank Praznik 	 * LEDs to on
1389ad142b9eSFrank Praznik 	 */
1390fa57a810SFrank Praznik 	sony_set_leds(sc, initial_values, sc->led_count);
1391f04d5140SColin Leitner 
13920a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1393f04d5140SColin Leitner 
1394fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
139561ebca93SFrank Praznik 
1396b3ed458cSFrank Praznik 		if (use_ds4_names)
1397b3ed458cSFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
139861ebca93SFrank Praznik 
1399f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1400f04d5140SColin Leitner 		if (!led) {
1401f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
14028cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1403f04d5140SColin Leitner 			goto error_leds;
1404f04d5140SColin Leitner 		}
1405f04d5140SColin Leitner 
1406f04d5140SColin Leitner 		name = (void *)(&led[1]);
1407b3ed458cSFrank Praznik 		if (use_ds4_names)
1408b3ed458cSFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1409b3ed458cSFrank Praznik 			ds4_name_str[n]);
141061ebca93SFrank Praznik 		else
14110a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1412f04d5140SColin Leitner 		led->name = name;
14138025087aSFrank Praznik 		led->brightness = initial_values[n];
1414b3ed458cSFrank Praznik 		led->max_brightness = max_brightness[n];
1415c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1416c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1417f04d5140SColin Leitner 
1418b3ed458cSFrank Praznik 		if (use_hw_blink[n])
1419b3ed458cSFrank Praznik 			led->blink_set = sony_led_blink_set;
1420b3ed458cSFrank Praznik 
14218025087aSFrank Praznik 		sc->leds[n] = led;
14228025087aSFrank Praznik 
14238cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
14248cd5fcdaSJulia Lawall 		if (ret) {
1425f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
14268025087aSFrank Praznik 			sc->leds[n] = NULL;
1427f04d5140SColin Leitner 			kfree(led);
1428f04d5140SColin Leitner 			goto error_leds;
1429f04d5140SColin Leitner 		}
1430f04d5140SColin Leitner 	}
1431f04d5140SColin Leitner 
1432f04d5140SColin Leitner 	return ret;
1433f04d5140SColin Leitner 
1434f04d5140SColin Leitner error_leds:
1435fa57a810SFrank Praznik 	sony_leds_remove(sc);
1436f04d5140SColin Leitner 
1437f04d5140SColin Leitner 	return ret;
1438f04d5140SColin Leitner }
1439f04d5140SColin Leitner 
1440cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
1441a08c22c0SSven Eckelmann {
144292b5c411SSven Eckelmann 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1443b3ed458cSFrank Praznik 	int n;
144455d3b664SFrank Praznik 	union sixaxis_output_report_01 report = {
144555d3b664SFrank Praznik 		.buf = {
1446a08c22c0SSven Eckelmann 			0x01,
1447a08c22c0SSven Eckelmann 			0x00, 0xff, 0x00, 0xff, 0x00,
14480a286ef2SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00,
1449a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1450a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1451a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1452a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1453a08c22c0SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00
145455d3b664SFrank Praznik 		}
1455a08c22c0SSven Eckelmann 	};
14569f323b68SSven Eckelmann 
14570a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
145855d3b664SFrank Praznik 	report.data.rumble.right_motor_on = sc->right ? 1 : 0;
145955d3b664SFrank Praznik 	report.data.rumble.left_motor_force = sc->left;
14600a286ef2SSven Eckelmann #endif
14610a286ef2SSven Eckelmann 
146255d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[0] << 1;
146355d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[1] << 2;
146455d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[2] << 3;
146555d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[3] << 4;
14669f323b68SSven Eckelmann 
146788f6576fSSimon Wood 	/* Set flag for all leds off, required for 3rd party INTEC controller */
146888f6576fSSimon Wood 	if ((report.data.leds_bitmap & 0x1E) == 0)
146988f6576fSSimon Wood 		report.data.leds_bitmap |= 0x20;
147088f6576fSSimon Wood 
1471b3ed458cSFrank Praznik 	/*
1472b3ed458cSFrank Praznik 	 * The LEDs in the report are indexed in reverse order to their
1473b3ed458cSFrank Praznik 	 * corresponding light on the controller.
1474b3ed458cSFrank Praznik 	 * Index 0 = LED 4, index 1 = LED 3, etc...
1475b3ed458cSFrank Praznik 	 *
1476b3ed458cSFrank Praznik 	 * In the case of both delay values being zero (blinking disabled) the
1477b3ed458cSFrank Praznik 	 * default report values should be used or the controller LED will be
1478b3ed458cSFrank Praznik 	 * always off.
1479b3ed458cSFrank Praznik 	 */
1480b3ed458cSFrank Praznik 	for (n = 0; n < 4; n++) {
1481b3ed458cSFrank Praznik 		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
1482b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_off = sc->led_delay_off[n];
1483b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_on = sc->led_delay_on[n];
1484b3ed458cSFrank Praznik 		}
1485b3ed458cSFrank Praznik 	}
1486b3ed458cSFrank Praznik 
148755d3b664SFrank Praznik 	hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
148855d3b664SFrank Praznik 			sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
14899f323b68SSven Eckelmann }
14909f323b68SSven Eckelmann 
14910bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
14920bd88dd3SFrank Praznik {
14930bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
14940da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
149548220237SFrank Praznik 	int offset;
14960da8ea65SFrank Praznik 
1497fdcf105dSFrank Praznik 	__u8 buf[78] = { 0 };
149848220237SFrank Praznik 
1499fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
150048220237SFrank Praznik 		buf[0] = 0x05;
1501b3ed458cSFrank Praznik 		buf[1] = 0xFF;
150248220237SFrank Praznik 		offset = 4;
1503fdcf105dSFrank Praznik 	} else {
1504fdcf105dSFrank Praznik 		buf[0] = 0x11;
1505fdcf105dSFrank Praznik 		buf[1] = 0xB0;
1506fdcf105dSFrank Praznik 		buf[3] = 0x0F;
1507fdcf105dSFrank Praznik 		offset = 6;
1508fdcf105dSFrank Praznik 	}
15090bd88dd3SFrank Praznik 
15100bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
151148220237SFrank Praznik 	buf[offset++] = sc->right;
151248220237SFrank Praznik 	buf[offset++] = sc->left;
151348220237SFrank Praznik #else
151448220237SFrank Praznik 	offset += 2;
15150bd88dd3SFrank Praznik #endif
15160bd88dd3SFrank Praznik 
1517b3ed458cSFrank Praznik 	/* LED 3 is the global control */
1518b3ed458cSFrank Praznik 	if (sc->led_state[3]) {
151948220237SFrank Praznik 		buf[offset++] = sc->led_state[0];
152048220237SFrank Praznik 		buf[offset++] = sc->led_state[1];
152148220237SFrank Praznik 		buf[offset++] = sc->led_state[2];
1522b3ed458cSFrank Praznik 	} else {
1523b3ed458cSFrank Praznik 		offset += 3;
1524b3ed458cSFrank Praznik 	}
1525b3ed458cSFrank Praznik 
1526b3ed458cSFrank Praznik 	/* If both delay values are zero the DualShock 4 disables blinking. */
1527b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_on[3];
1528b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_off[3];
152960781cf4SFrank Praznik 
1530fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1531fdcf105dSFrank Praznik 		hid_hw_output_report(hdev, buf, 32);
1532fdcf105dSFrank Praznik 	else
1533fdcf105dSFrank Praznik 		hid_hw_raw_request(hdev, 0x11, buf, 78,
1534fdcf105dSFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
15350bd88dd3SFrank Praznik }
15360bd88dd3SFrank Praznik 
15370a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
15389f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
15399f323b68SSven Eckelmann 			    struct ff_effect *effect)
15409f323b68SSven Eckelmann {
1541a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
15429f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
1543a08c22c0SSven Eckelmann 
1544a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
1545a08c22c0SSven Eckelmann 		return 0;
1546a08c22c0SSven Eckelmann 
15479f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
15480bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
1549a08c22c0SSven Eckelmann 
155092b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
15519f323b68SSven Eckelmann 	return 0;
1552a08c22c0SSven Eckelmann }
1553a08c22c0SSven Eckelmann 
1554fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1555a08c22c0SSven Eckelmann {
1556fa57a810SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1557a08c22c0SSven Eckelmann 						struct hid_input, list);
1558a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
1559a08c22c0SSven Eckelmann 
1560a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1561a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1562a08c22c0SSven Eckelmann }
1563a08c22c0SSven Eckelmann 
1564a08c22c0SSven Eckelmann #else
1565fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1566a08c22c0SSven Eckelmann {
1567a08c22c0SSven Eckelmann 	return 0;
1568a08c22c0SSven Eckelmann }
15699f323b68SSven Eckelmann 
1570a08c22c0SSven Eckelmann #endif
1571a08c22c0SSven Eckelmann 
1572d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
1573d902f472SFrank Praznik 				     enum power_supply_property psp,
1574d902f472SFrank Praznik 				     union power_supply_propval *val)
1575c4e1ddf2SFrank Praznik {
1576d902f472SFrank Praznik 	struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
1577d902f472SFrank Praznik 	unsigned long flags;
1578d902f472SFrank Praznik 	int ret = 0;
1579d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
1580c4e1ddf2SFrank Praznik 
1581d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1582d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
1583d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
1584d902f472SFrank Praznik 	cable_state = sc->cable_state;
1585d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1586c4e1ddf2SFrank Praznik 
1587d902f472SFrank Praznik 	switch (psp) {
1588d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
1589d902f472SFrank Praznik 		val->intval = 1;
1590d902f472SFrank Praznik 		break;
1591d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
1592d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1593d902f472SFrank Praznik 		break;
1594d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
1595d902f472SFrank Praznik 		val->intval = battery_capacity;
1596d902f472SFrank Praznik 		break;
1597d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
1598d902f472SFrank Praznik 		if (battery_charging)
1599d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
1600d902f472SFrank Praznik 		else
1601d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
1602d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
1603d902f472SFrank Praznik 			else
1604d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1605d902f472SFrank Praznik 		break;
1606d902f472SFrank Praznik 	default:
1607d902f472SFrank Praznik 		ret = -EINVAL;
1608d902f472SFrank Praznik 		break;
1609c4e1ddf2SFrank Praznik 	}
1610d902f472SFrank Praznik 	return ret;
1611d902f472SFrank Praznik }
1612d902f472SFrank Praznik 
1613d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc)
1614d902f472SFrank Praznik {
1615d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1616d902f472SFrank Praznik 	int ret;
1617d902f472SFrank Praznik 
1618ad142b9eSFrank Praznik 	/*
1619ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
1620d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
1621d9a293a9SFrank Praznik 	 */
1622d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
1623d9a293a9SFrank Praznik 
1624d902f472SFrank Praznik 	sc->battery.properties = sony_battery_props;
1625d902f472SFrank Praznik 	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
1626d902f472SFrank Praznik 	sc->battery.get_property = sony_battery_get_property;
1627d902f472SFrank Praznik 	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1628d902f472SFrank Praznik 	sc->battery.use_for_apm = 0;
1629314531f1SFrank Praznik 	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR",
1630314531f1SFrank Praznik 				     sc->mac_address);
1631d902f472SFrank Praznik 	if (!sc->battery.name)
1632d902f472SFrank Praznik 		return -ENOMEM;
1633d902f472SFrank Praznik 
1634d902f472SFrank Praznik 	ret = power_supply_register(&hdev->dev, &sc->battery);
1635d902f472SFrank Praznik 	if (ret) {
1636d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
1637d902f472SFrank Praznik 		goto err_free;
1638d902f472SFrank Praznik 	}
1639d902f472SFrank Praznik 
1640d902f472SFrank Praznik 	power_supply_powers(&sc->battery, &hdev->dev);
1641d902f472SFrank Praznik 	return 0;
1642d902f472SFrank Praznik 
1643d902f472SFrank Praznik err_free:
1644d902f472SFrank Praznik 	kfree(sc->battery.name);
1645d902f472SFrank Praznik 	sc->battery.name = NULL;
1646d902f472SFrank Praznik 	return ret;
1647d902f472SFrank Praznik }
1648d902f472SFrank Praznik 
1649d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
1650d902f472SFrank Praznik {
1651d902f472SFrank Praznik 	if (!sc->battery.name)
1652d902f472SFrank Praznik 		return;
1653d902f472SFrank Praznik 
1654d902f472SFrank Praznik 	power_supply_unregister(&sc->battery);
1655d902f472SFrank Praznik 	kfree(sc->battery.name);
1656d902f472SFrank Praznik 	sc->battery.name = NULL;
1657d902f472SFrank Praznik }
1658d902f472SFrank Praznik 
1659e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1660e5606230SFrank Praznik 					int w, int h)
1661e5606230SFrank Praznik {
1662e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1663e5606230SFrank Praznik 						struct hid_input, list);
1664e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
1665e5606230SFrank Praznik 	int ret;
1666e5606230SFrank Praznik 
1667e5606230SFrank Praznik 	ret = input_mt_init_slots(input_dev, touch_count, 0);
1668e5606230SFrank Praznik 	if (ret < 0) {
1669e5606230SFrank Praznik 		hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
1670e5606230SFrank Praznik 		return ret;
1671e5606230SFrank Praznik 	}
1672e5606230SFrank Praznik 
1673e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1674e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1675e5606230SFrank Praznik 
1676c4e1ddf2SFrank Praznik 	return 0;
1677c4e1ddf2SFrank Praznik }
1678e5606230SFrank Praznik 
1679d2d782fcSFrank Praznik /*
1680d2d782fcSFrank Praznik  * If a controller is plugged in via USB while already connected via Bluetooth
1681d2d782fcSFrank Praznik  * it will show up as two devices. A global list of connected controllers and
1682d2d782fcSFrank Praznik  * their MAC addresses is maintained to ensure that a device is only connected
1683d2d782fcSFrank Praznik  * once.
1684d2d782fcSFrank Praznik  */
1685d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc)
1686d2d782fcSFrank Praznik {
1687d2d782fcSFrank Praznik 	struct sony_sc *entry;
1688d2d782fcSFrank Praznik 	unsigned long flags;
1689d2d782fcSFrank Praznik 	int ret;
1690d2d782fcSFrank Praznik 
1691d2d782fcSFrank Praznik 	spin_lock_irqsave(&sony_dev_list_lock, flags);
1692d2d782fcSFrank Praznik 
1693d2d782fcSFrank Praznik 	list_for_each_entry(entry, &sony_device_list, list_node) {
1694d2d782fcSFrank Praznik 		ret = memcmp(sc->mac_address, entry->mac_address,
1695d2d782fcSFrank Praznik 				sizeof(sc->mac_address));
1696d2d782fcSFrank Praznik 		if (!ret) {
1697d2d782fcSFrank Praznik 			ret = -EEXIST;
1698d2d782fcSFrank Praznik 			hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",
1699d2d782fcSFrank Praznik 				sc->mac_address);
1700d2d782fcSFrank Praznik 			goto unlock;
1701d2d782fcSFrank Praznik 		}
1702c4e1ddf2SFrank Praznik 	}
1703c4e1ddf2SFrank Praznik 
1704d2d782fcSFrank Praznik 	ret = 0;
1705d2d782fcSFrank Praznik 	list_add(&(sc->list_node), &sony_device_list);
1706c4e1ddf2SFrank Praznik 
1707d2d782fcSFrank Praznik unlock:
1708d2d782fcSFrank Praznik 	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1709d2d782fcSFrank Praznik 	return ret;
1710d2d782fcSFrank Praznik }
1711d2d782fcSFrank Praznik 
1712d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc)
1713d2d782fcSFrank Praznik {
1714d2d782fcSFrank Praznik 	unsigned long flags;
1715d2d782fcSFrank Praznik 
1716d2d782fcSFrank Praznik 	if (sc->list_node.next) {
1717d2d782fcSFrank Praznik 		spin_lock_irqsave(&sony_dev_list_lock, flags);
1718d2d782fcSFrank Praznik 		list_del(&(sc->list_node));
1719d2d782fcSFrank Praznik 		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1720d2d782fcSFrank Praznik 	}
1721d2d782fcSFrank Praznik }
1722d2d782fcSFrank Praznik 
1723d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc)
1724d2d782fcSFrank Praznik {
1725d2d782fcSFrank Praznik 	int ret;
1726d2d782fcSFrank Praznik 
1727d2d782fcSFrank Praznik 	/* HIDP stores the device MAC address as a string in the uniq field. */
1728d2d782fcSFrank Praznik 	ret = strlen(sc->hdev->uniq);
1729d2d782fcSFrank Praznik 	if (ret != 17)
1730c4e1ddf2SFrank Praznik 		return -EINVAL;
1731d2d782fcSFrank Praznik 
1732d2d782fcSFrank Praznik 	ret = sscanf(sc->hdev->uniq,
1733d2d782fcSFrank Praznik 		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1734d2d782fcSFrank Praznik 		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
1735d2d782fcSFrank Praznik 		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
1736d2d782fcSFrank Praznik 
1737d2d782fcSFrank Praznik 	if (ret != 6)
1738d2d782fcSFrank Praznik 		return -EINVAL;
1739d2d782fcSFrank Praznik 
1740d2d782fcSFrank Praznik 	return 0;
1741c4e1ddf2SFrank Praznik }
1742c4e1ddf2SFrank Praznik 
1743d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc)
1744d2d782fcSFrank Praznik {
1745d2d782fcSFrank Praznik 	int n, ret;
1746d2d782fcSFrank Praznik 
1747d2d782fcSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
1748d2d782fcSFrank Praznik 	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
1749d2d782fcSFrank Praznik 		/*
1750d2d782fcSFrank Praznik 		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
1751d2d782fcSFrank Praznik 		 * address from the uniq string where HIDP stores it.
1752d2d782fcSFrank Praznik 		 * As uniq cannot be guaranteed to be a MAC address in all cases
1753d2d782fcSFrank Praznik 		 * a failure of this function should not prevent the connection.
1754d2d782fcSFrank Praznik 		 */
1755d2d782fcSFrank Praznik 		if (sony_get_bt_devaddr(sc) < 0) {
1756d2d782fcSFrank Praznik 			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");
1757d2d782fcSFrank Praznik 			return 0;
1758d2d782fcSFrank Praznik 		}
1759d2d782fcSFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
1760d2d782fcSFrank Praznik 		__u8 buf[7];
1761d2d782fcSFrank Praznik 
1762d2d782fcSFrank Praznik 		/*
1763d2d782fcSFrank Praznik 		 * The MAC address of a DS4 controller connected via USB can be
1764d2d782fcSFrank Praznik 		 * retrieved with feature report 0x81. The address begins at
1765d2d782fcSFrank Praznik 		 * offset 1.
1766d2d782fcSFrank Praznik 		 */
1767d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf),
1768d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1769d2d782fcSFrank Praznik 
1770d2d782fcSFrank Praznik 		if (ret != 7) {
1771d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
1772d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1773d2d782fcSFrank Praznik 		}
1774d2d782fcSFrank Praznik 
1775d2d782fcSFrank Praznik 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
1776d2d782fcSFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1777d2d782fcSFrank Praznik 		__u8 buf[18];
1778d2d782fcSFrank Praznik 
1779d2d782fcSFrank Praznik 		/*
1780d2d782fcSFrank Praznik 		 * The MAC address of a Sixaxis controller connected via USB can
1781d2d782fcSFrank Praznik 		 * be retrieved with feature report 0xf2. The address begins at
1782d2d782fcSFrank Praznik 		 * offset 4.
1783d2d782fcSFrank Praznik 		 */
1784d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf),
1785d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1786d2d782fcSFrank Praznik 
1787d2d782fcSFrank Praznik 		if (ret != 18) {
1788d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");
1789d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1790d2d782fcSFrank Praznik 		}
1791d2d782fcSFrank Praznik 
1792d2d782fcSFrank Praznik 		/*
1793d2d782fcSFrank Praznik 		 * The Sixaxis device MAC in the report is big-endian and must
1794d2d782fcSFrank Praznik 		 * be byte-swapped.
1795d2d782fcSFrank Praznik 		 */
1796d2d782fcSFrank Praznik 		for (n = 0; n < 6; n++)
1797d2d782fcSFrank Praznik 			sc->mac_address[5-n] = buf[4+n];
1798d2d782fcSFrank Praznik 	} else {
1799d2d782fcSFrank Praznik 		return 0;
1800d2d782fcSFrank Praznik 	}
1801d2d782fcSFrank Praznik 
1802d2d782fcSFrank Praznik 	return sony_check_add_dev_list(sc);
1803d2d782fcSFrank Praznik }
1804d2d782fcSFrank Praznik 
18058025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc)
18068025087aSFrank Praznik {
18078025087aSFrank Praznik 	int ret;
18088025087aSFrank Praznik 
18098025087aSFrank Praznik 	/*
18108025087aSFrank Praznik 	 * Only DualShock 4 or Sixaxis controllers get an id.
18118025087aSFrank Praznik 	 * All others are set to -1.
18128025087aSFrank Praznik 	 */
18138025087aSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
18148025087aSFrank Praznik 	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
18158025087aSFrank Praznik 		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
18168025087aSFrank Praznik 					GFP_KERNEL);
18178025087aSFrank Praznik 		if (ret < 0) {
18188025087aSFrank Praznik 			sc->device_id = -1;
18198025087aSFrank Praznik 			return ret;
18208025087aSFrank Praznik 		}
18218025087aSFrank Praznik 		sc->device_id = ret;
18228025087aSFrank Praznik 	} else {
18238025087aSFrank Praznik 		sc->device_id = -1;
18248025087aSFrank Praznik 	}
18258025087aSFrank Praznik 
18268025087aSFrank Praznik 	return 0;
18278025087aSFrank Praznik }
18288025087aSFrank Praznik 
18298025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc)
18308025087aSFrank Praznik {
18318025087aSFrank Praznik 	if (sc->device_id >= 0) {
18328025087aSFrank Praznik 		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
18338025087aSFrank Praznik 		sc->device_id = -1;
18348025087aSFrank Praznik 	}
18358025087aSFrank Praznik }
18368025087aSFrank Praznik 
183746262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc,
183846262047SFrank Praznik 					void (*worker)(struct work_struct *))
183946262047SFrank Praznik {
184046262047SFrank Praznik 	if (!sc->worker_initialized)
184146262047SFrank Praznik 		INIT_WORK(&sc->state_worker, worker);
184246262047SFrank Praznik 
184346262047SFrank Praznik 	sc->worker_initialized = 1;
184446262047SFrank Praznik }
184546262047SFrank Praznik 
184646262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc)
184746262047SFrank Praznik {
184846262047SFrank Praznik 	if (sc->worker_initialized)
184946262047SFrank Praznik 		cancel_work_sync(&sc->state_worker);
185046262047SFrank Praznik }
1851d2d782fcSFrank Praznik 
1852bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1853bd28ce00SJiri Slaby {
1854bd28ce00SJiri Slaby 	int ret;
1855cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
1856cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
1857f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
1858cc6e0bbbSJiri Kosina 
1859abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
1860cc6e0bbbSJiri Kosina 	if (sc == NULL) {
18614291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
1862cc6e0bbbSJiri Kosina 		return -ENOMEM;
1863cc6e0bbbSJiri Kosina 	}
1864cc6e0bbbSJiri Kosina 
1865cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
1866cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
18670a286ef2SSven Eckelmann 	sc->hdev = hdev;
1868bd28ce00SJiri Slaby 
1869bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
1870bd28ce00SJiri Slaby 	if (ret) {
18714291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
1872abf832bfSBenjamin Tissoires 		return ret;
1873bd28ce00SJiri Slaby 	}
1874bd28ce00SJiri Slaby 
1875f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
1876f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
187750764650SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER)
1878f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1879f04d5140SColin Leitner 
1880f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
1881bd28ce00SJiri Slaby 	if (ret) {
18824291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
1883abf832bfSBenjamin Tissoires 		return ret;
1884bd28ce00SJiri Slaby 	}
1885bd28ce00SJiri Slaby 
18868025087aSFrank Praznik 	ret = sony_set_device_id(sc);
18878025087aSFrank Praznik 	if (ret < 0) {
18888025087aSFrank Praznik 		hid_err(hdev, "failed to allocate the device id\n");
18898025087aSFrank Praznik 		goto err_stop;
18908025087aSFrank Praznik 	}
18918025087aSFrank Praznik 
1892569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1893e534a935SBenjamin Tissoires 		/*
1894e534a935SBenjamin Tissoires 		 * The Sony Sixaxis does not handle HID Output Reports on the
1895e534a935SBenjamin Tissoires 		 * Interrupt EP like it could, so we need to force HID Output
1896e534a935SBenjamin Tissoires 		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
1897e534a935SBenjamin Tissoires 		 *
1898e534a935SBenjamin Tissoires 		 * There is also another issue about HID Output Reports via USB,
1899e534a935SBenjamin Tissoires 		 * the Sixaxis does not want the report_id as part of the data
1900e534a935SBenjamin Tissoires 		 * packet, so we have to discard buf[0] when sending the actual
1901e534a935SBenjamin Tissoires 		 * control message, even for numbered reports, humpf!
1902e534a935SBenjamin Tissoires 		 */
1903e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1904e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
1905816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
190646262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1907fee4e2d5SFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
19082078b9bbSFrank Praznik 		/*
19092078b9bbSFrank Praznik 		 * The Sixaxis wants output reports sent on the ctrl endpoint
19102078b9bbSFrank Praznik 		 * when connected via Bluetooth.
19112078b9bbSFrank Praznik 		 */
19122078b9bbSFrank Praznik 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1913816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
191446262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1915fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
191668330d83SFrank Praznik 		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
19172078b9bbSFrank Praznik 			/*
19182078b9bbSFrank Praznik 			 * The DualShock 4 wants output reports sent on the ctrl
19192078b9bbSFrank Praznik 			 * endpoint when connected via Bluetooth.
19202078b9bbSFrank Praznik 			 */
19212078b9bbSFrank Praznik 			hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
192268330d83SFrank Praznik 			ret = dualshock4_set_operational_bt(hdev);
192368330d83SFrank Praznik 			if (ret < 0) {
192468330d83SFrank Praznik 				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
192568330d83SFrank Praznik 				goto err_stop;
192668330d83SFrank Praznik 			}
192768330d83SFrank Praznik 		}
1928ad142b9eSFrank Praznik 		/*
1929ad142b9eSFrank Praznik 		 * The Dualshock 4 touchpad supports 2 touches and has a
1930e5606230SFrank Praznik 		 * resolution of 1920x940.
1931e5606230SFrank Praznik 		 */
1932e5606230SFrank Praznik 		ret = sony_register_touchpad(sc, 2, 1920, 940);
1933c4e1ddf2SFrank Praznik 		if (ret < 0)
1934c4e1ddf2SFrank Praznik 			goto err_stop;
1935c4e1ddf2SFrank Praznik 
193646262047SFrank Praznik 		sony_init_work(sc, dualshock4_state_worker);
19370bd88dd3SFrank Praznik 	} else {
19380bd88dd3SFrank Praznik 		ret = 0;
19390bd88dd3SFrank Praznik 	}
1940f9ce7c28SBastien Nocera 
19414dfdc464SJiri Kosina 	if (ret < 0)
1942bd28ce00SJiri Slaby 		goto err_stop;
1943bd28ce00SJiri Slaby 
1944d2d782fcSFrank Praznik 	ret = sony_check_add(sc);
1945d2d782fcSFrank Praznik 	if (ret < 0)
1946d2d782fcSFrank Praznik 		goto err_stop;
1947d2d782fcSFrank Praznik 
19480a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
1949fa57a810SFrank Praznik 		ret = sony_leds_init(sc);
19500a286ef2SSven Eckelmann 		if (ret < 0)
19510a286ef2SSven Eckelmann 			goto err_stop;
19520a286ef2SSven Eckelmann 	}
19530a286ef2SSven Eckelmann 
1954d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1955d902f472SFrank Praznik 		ret = sony_battery_probe(sc);
1956a08c22c0SSven Eckelmann 		if (ret < 0)
1957a08c22c0SSven Eckelmann 			goto err_stop;
1958a08c22c0SSven Eckelmann 
1959d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
1960d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
1961d902f472SFrank Praznik 		if (ret < 0) {
1962d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
1963d902f472SFrank Praznik 			goto err_stop;
1964d902f472SFrank Praznik 		}
1965d902f472SFrank Praznik 	}
1966d902f472SFrank Praznik 
1967c8de9dbbSFrank Praznik 	if (sc->quirks & SONY_FF_SUPPORT) {
1968fa57a810SFrank Praznik 		ret = sony_init_ff(sc);
1969d902f472SFrank Praznik 		if (ret < 0)
1970d902f472SFrank Praznik 			goto err_close;
19715f5750d2SFrank Praznik 	}
1972bd28ce00SJiri Slaby 
1973f425458eSH Hartley Sweeten 	return 0;
1974d902f472SFrank Praznik err_close:
1975d902f472SFrank Praznik 	hid_hw_close(hdev);
1976bd28ce00SJiri Slaby err_stop:
19770a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1978fa57a810SFrank Praznik 		sony_leds_remove(sc);
1979d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
1980d902f472SFrank Praznik 		sony_battery_remove(sc);
198146262047SFrank Praznik 	sony_cancel_work_sync(sc);
1982d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
19838025087aSFrank Praznik 	sony_release_device_id(sc);
1984bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
1985bd28ce00SJiri Slaby 	return ret;
1986bd28ce00SJiri Slaby }
1987bd28ce00SJiri Slaby 
1988bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev)
1989bd28ce00SJiri Slaby {
1990bd28ce00SJiri Slaby 	struct sony_sc *sc = hid_get_drvdata(hdev);
1991bd28ce00SJiri Slaby 
19920a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1993fa57a810SFrank Praznik 		sony_leds_remove(sc);
1994bd28ce00SJiri Slaby 
1995d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1996d902f472SFrank Praznik 		hid_hw_close(hdev);
1997d902f472SFrank Praznik 		sony_battery_remove(sc);
1998d902f472SFrank Praznik 	}
1999d902f472SFrank Praznik 
200046262047SFrank Praznik 	sony_cancel_work_sync(sc);
20019f323b68SSven Eckelmann 
2002d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
2003bd28ce00SJiri Slaby 
20048025087aSFrank Praznik 	sony_release_device_id(sc);
20058025087aSFrank Praznik 
2006bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2007bd28ce00SJiri Slaby }
2008bd28ce00SJiri Slaby 
2009bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
2010bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2011bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2012bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
2013bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2014bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2015bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_BT },
2016bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
2017bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2018bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
2019bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2020bd28ce00SJiri Slaby 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
2021bd28ce00SJiri Slaby 	 * Logitech joystick from the device descriptor. */
2022bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
2023bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2024bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
2025bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2026bd28ce00SJiri Slaby 	/* PS3 BD Remote Control */
2027bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
2028bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
2029bd28ce00SJiri Slaby 	/* Logitech Harmony Adapter for PS3 */
2030bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
2031bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
20320bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
20330bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
20348ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
20350bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
20368ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
2037bd28ce00SJiri Slaby 	{ }
2038bd28ce00SJiri Slaby };
2039bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
2040bd28ce00SJiri Slaby 
2041bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
2042bd28ce00SJiri Slaby 	.name          = "sony",
2043bd28ce00SJiri Slaby 	.id_table      = sony_devices,
2044bd28ce00SJiri Slaby 	.input_mapping = sony_mapping,
2045bd28ce00SJiri Slaby 	.probe         = sony_probe,
2046bd28ce00SJiri Slaby 	.remove        = sony_remove,
2047bd28ce00SJiri Slaby 	.report_fixup  = sony_report_fixup,
2048bd28ce00SJiri Slaby 	.raw_event     = sony_raw_event
2049bd28ce00SJiri Slaby };
20508025087aSFrank Praznik 
20518025087aSFrank Praznik static int __init sony_init(void)
20528025087aSFrank Praznik {
20538025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20548025087aSFrank Praznik 
20558025087aSFrank Praznik 	return hid_register_driver(&sony_driver);
20568025087aSFrank Praznik }
20578025087aSFrank Praznik 
20588025087aSFrank Praznik static void __exit sony_exit(void)
20598025087aSFrank Praznik {
20608025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20618025087aSFrank Praznik 
20628025087aSFrank Praznik 	ida_destroy(&sony_device_id_allocator);
20638025087aSFrank Praznik 	hid_unregister_driver(&sony_driver);
20648025087aSFrank Praznik }
20658025087aSFrank Praznik module_init(sony_init);
20668025087aSFrank Praznik module_exit(sony_exit);
2067bd28ce00SJiri Slaby 
2068bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
2069