xref: /linux/drivers/hid/hid-sony.c (revision fb291cbd3f9f7bd5873f112a6924b650440779c6)
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[] = {
60fb705a6dSAntonio Ospite 	0x05, 0x01,         /*  Usage Page (Desktop),               */
61fb705a6dSAntonio Ospite 	0x09, 0x04,         /*  Usage (Joystik),                    */
62fb705a6dSAntonio Ospite 	0xA1, 0x01,         /*  Collection (Application),           */
63fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
64fb705a6dSAntonio Ospite 	0x85, 0x01,         /*          Report ID (1),              */
65fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
66fb705a6dSAntonio Ospite 	0x95, 0x01,         /*          Report Count (1),           */
67fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
68fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
69fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
70fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
71fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
72fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
73fb705a6dSAntonio Ospite 	0x25, 0x01,         /*          Logical Maximum (1),        */
74fb705a6dSAntonio Ospite 	0x35, 0x00,         /*          Physical Minimum (0),       */
75fb705a6dSAntonio Ospite 	0x45, 0x01,         /*          Physical Maximum (1),       */
76fb705a6dSAntonio Ospite 	0x05, 0x09,         /*          Usage Page (Button),        */
77fb705a6dSAntonio Ospite 	0x19, 0x01,         /*          Usage Minimum (01h),        */
78fb705a6dSAntonio Ospite 	0x29, 0x13,         /*          Usage Maximum (13h),        */
79fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
80fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
81fb705a6dSAntonio Ospite 	0x95, 0x0D,         /*          Report Count (13),          */
82fb705a6dSAntonio Ospite 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
83fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
84fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
85fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
86fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
87fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
88fb705a6dSAntonio Ospite 	0xA1, 0x00,         /*          Collection (Physical),      */
89fb705a6dSAntonio Ospite 	0x75, 0x08,         /*              Report Size (8),        */
90fb705a6dSAntonio Ospite 	0x95, 0x04,         /*              Report Count (4),       */
91fb705a6dSAntonio Ospite 	0x35, 0x00,         /*              Physical Minimum (0),   */
92fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
93fb705a6dSAntonio Ospite 	0x09, 0x30,         /*              Usage (X),              */
94fb705a6dSAntonio Ospite 	0x09, 0x31,         /*              Usage (Y),              */
95fb705a6dSAntonio Ospite 	0x09, 0x32,         /*              Usage (Z),              */
96fb705a6dSAntonio Ospite 	0x09, 0x35,         /*              Usage (Rz),             */
97fb705a6dSAntonio Ospite 	0x81, 0x02,         /*              Input (Variable),       */
98fb705a6dSAntonio Ospite 	0xC0,               /*          End Collection,             */
99fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
100fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
101fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
102fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
103fb705a6dSAntonio Ospite 	0x95, 0x0C,         /*          Report Count (12),          */
104fb705a6dSAntonio Ospite 	0x81, 0x01,         /*          Input (Constant),           */
105fb705a6dSAntonio Ospite 	0x75, 0x10,         /*          Report Size (16),           */
106fb705a6dSAntonio Ospite 	0x95, 0x04,         /*          Report Count (4),           */
107fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
108fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
109fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
110fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
111fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
112fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
113fb705a6dSAntonio Ospite 	0x85, 0x02,         /*          Report ID (2),              */
114fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
115fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
116fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
117fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
118fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
119fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
120fb705a6dSAntonio Ospite 	0x85, 0xEE,         /*          Report ID (238),            */
121fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
122fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
123fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
124fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
125fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
126fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
127fb705a6dSAntonio Ospite 	0x85, 0xEF,         /*          Report ID (239),            */
128fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
129fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
130fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
131fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
132fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
133fb705a6dSAntonio 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),            */
179*fb291cbdSFrank Praznik 	0x25, 0x3F,         /*      Logical Maximum (63),           */
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),            */
203*fb291cbdSFrank Praznik 	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
204*fb291cbdSFrank Praznik 	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
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),            */
210*fb291cbdSFrank Praznik 	0x26, 0xFF, 0x00,   /*      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),            */
512*fb291cbdSFrank Praznik 	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
513*fb291cbdSFrank Praznik 	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
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 
87873e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
87973e4008dSNikolai Kondrashov 		unsigned int *rsize)
880cc6e0bbbSJiri Kosina {
881cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
882cc6e0bbbSJiri Kosina 
88399d24902SFernando Luis Vázquez Cao 	/*
88499d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
88599d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
88699d24902SFernando Luis Vázquez Cao 	 */
88799d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
88899d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
88999d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
89099d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
89199d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
89299d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
89399d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
894a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
89599d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
896cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
897cc6e0bbbSJiri Kosina 	}
89861ab44beSSimon Wood 
899ed19d8cfSFrank Praznik 	/*
900ed19d8cfSFrank Praznik 	 * The default Dualshock 4 USB descriptor doesn't assign
901ed19d8cfSFrank Praznik 	 * the gyroscope values to corresponding axes so we need a
902ed19d8cfSFrank Praznik 	 * modified one.
903ed19d8cfSFrank Praznik 	 */
904ed19d8cfSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
905ed19d8cfSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
906ed19d8cfSFrank Praznik 		rdesc = dualshock4_usb_rdesc;
907ed19d8cfSFrank Praznik 		*rsize = sizeof(dualshock4_usb_rdesc);
908d829674dSFrank Praznik 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
909d829674dSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
910d829674dSFrank Praznik 		rdesc = dualshock4_bt_rdesc;
911d829674dSFrank Praznik 		*rsize = sizeof(dualshock4_bt_rdesc);
912ed19d8cfSFrank Praznik 	}
913ed19d8cfSFrank Praznik 
914c607fb8dSAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER)
915c607fb8dSAntonio Ospite 		return sixaxis_fixup(hdev, rdesc, rsize);
916078328daSJiri Kosina 
917078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
918078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
919078328daSJiri Kosina 
92073e4008dSNikolai Kondrashov 	return rdesc;
921cc6e0bbbSJiri Kosina }
922cc6e0bbbSJiri Kosina 
923d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
924d902f472SFrank Praznik {
925d902f472SFrank Praznik 	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
926d902f472SFrank Praznik 	unsigned long flags;
927d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
928d902f472SFrank Praznik 
929ad142b9eSFrank Praznik 	/*
930ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
931d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
932d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
933d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
934d902f472SFrank Praznik 	 */
935d902f472SFrank Praznik 	if (rd[30] >= 0xee) {
936d902f472SFrank Praznik 		battery_capacity = 100;
937a43e94a3SFrank Praznik 		battery_charging = !(rd[30] & 0x01);
9389fddd74aSFrank Praznik 		cable_state = 1;
939d902f472SFrank Praznik 	} else {
940ac3c9a94SFrank Praznik 		__u8 index = rd[30] <= 5 ? rd[30] : 5;
941ac3c9a94SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[index];
942d902f472SFrank Praznik 		battery_charging = 0;
9439fddd74aSFrank Praznik 		cable_state = 0;
944d902f472SFrank Praznik 	}
945d902f472SFrank Praznik 
946d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
947d902f472SFrank Praznik 	sc->cable_state = cable_state;
948d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
949d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
950d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
951d902f472SFrank Praznik }
952d902f472SFrank Praznik 
953d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
954d902f472SFrank Praznik {
955e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
956e5606230SFrank Praznik 						struct hid_input, list);
957e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
958d902f472SFrank Praznik 	unsigned long flags;
9596c5f860dSFrank Praznik 	int n, offset;
960d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
961d902f472SFrank Praznik 
962ad142b9eSFrank Praznik 	/*
963ad142b9eSFrank Praznik 	 * Battery and touchpad data starts at byte 30 in the USB report and
9646c5f860dSFrank Praznik 	 * 32 in Bluetooth report.
9656c5f860dSFrank Praznik 	 */
9666c5f860dSFrank Praznik 	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
9676c5f860dSFrank Praznik 
968ad142b9eSFrank Praznik 	/*
969ad142b9eSFrank Praznik 	 * The lower 4 bits of byte 30 contain the battery level
970d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
971d902f472SFrank Praznik 	 */
9726c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
9736c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
974d902f472SFrank Praznik 
975ad142b9eSFrank Praznik 	/*
976ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
9776c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
9786c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
979d902f472SFrank Praznik 	 */
9806c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
981d902f472SFrank Praznik 		battery_charging = 0;
982d902f472SFrank Praznik 	else
983d902f472SFrank Praznik 		battery_charging = 1;
984d902f472SFrank Praznik 
9856c5f860dSFrank Praznik 	if (!cable_state)
9866c5f860dSFrank Praznik 		battery_capacity++;
987d902f472SFrank Praznik 	if (battery_capacity > 10)
9886c5f860dSFrank Praznik 		battery_capacity = 10;
9896c5f860dSFrank Praznik 
990d902f472SFrank Praznik 	battery_capacity *= 10;
991d902f472SFrank Praznik 
992d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
993d902f472SFrank Praznik 	sc->cable_state = cable_state;
994d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
995d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
996d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
997e5606230SFrank Praznik 
9986c5f860dSFrank Praznik 	offset += 5;
9996c5f860dSFrank Praznik 
1000ad142b9eSFrank Praznik 	/*
1001ad142b9eSFrank Praznik 	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
10026c5f860dSFrank Praznik 	 * and 37 on Bluetooth.
1003e5606230SFrank Praznik 	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
1004e5606230SFrank Praznik 	 * indicator that is 0 when pressed and 1 when not pressed.
1005e5606230SFrank Praznik 	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
1006e5606230SFrank Praznik 	 * The data for the second touch is in the same format and immediatly
1007e5606230SFrank Praznik 	 * follows the data for the first.
1008e5606230SFrank Praznik 	 */
1009e5606230SFrank Praznik 	for (n = 0; n < 2; n++) {
1010e5606230SFrank Praznik 		__u16 x, y;
1011e5606230SFrank Praznik 
1012e5606230SFrank Praznik 		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
1013e5606230SFrank Praznik 		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
1014e5606230SFrank Praznik 
1015e5606230SFrank Praznik 		input_mt_slot(input_dev, n);
1016e5606230SFrank Praznik 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
1017e5606230SFrank Praznik 					!(rd[offset] >> 7));
1018e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
1019e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
1020e5606230SFrank Praznik 
1021e5606230SFrank Praznik 		offset += 4;
1022e5606230SFrank Praznik 	}
1023d902f472SFrank Praznik }
1024d902f472SFrank Praznik 
1025c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
1026c9e4d877SSimon Wood 		__u8 *rd, int size)
1027c9e4d877SSimon Wood {
1028c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
1029c9e4d877SSimon Wood 
1030ad142b9eSFrank Praznik 	/*
1031ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
1032c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
1033c9e4d877SSimon Wood 	 */
1034fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
1035c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
1036c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
1037c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
1038c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
1039d902f472SFrank Praznik 
1040d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
104168330d83SFrank Praznik 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
104268330d83SFrank Praznik 			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
104368330d83SFrank Praznik 			&& rd[0] == 0x11 && size == 78)) {
1044d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
1045c9e4d877SSimon Wood 	}
1046c9e4d877SSimon Wood 
1047c9e4d877SSimon Wood 	return 0;
1048c9e4d877SSimon Wood }
1049c9e4d877SSimon Wood 
1050f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
1051f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
1052f04d5140SColin Leitner 			unsigned long **bit, int *max)
1053f04d5140SColin Leitner {
1054f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1055f04d5140SColin Leitner 
1056f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
1057f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
1058f04d5140SColin Leitner 
1059f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
1060f04d5140SColin Leitner 			return -1;
1061f04d5140SColin Leitner 
1062f04d5140SColin Leitner 		switch (usage->collection_index) {
1063f04d5140SColin Leitner 		case 1:
1064f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
1065f04d5140SColin Leitner 				return -1;
1066f04d5140SColin Leitner 
1067f04d5140SColin Leitner 			key = buzz_keymap[key];
1068f04d5140SColin Leitner 			if (!key)
1069f04d5140SColin Leitner 				return -1;
1070f04d5140SColin Leitner 			break;
1071f04d5140SColin Leitner 		default:
1072f04d5140SColin Leitner 			return -1;
1073f04d5140SColin Leitner 		}
1074f04d5140SColin Leitner 
1075f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1076f04d5140SColin Leitner 		return 1;
1077f04d5140SColin Leitner 	}
1078f04d5140SColin Leitner 
1079078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1080078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
1081078328daSJiri Kosina 
10826f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
10836f498018SBenjamin Tissoires 	return 0;
1084f04d5140SColin Leitner }
1085f04d5140SColin Leitner 
10865710fabfSAntonio Ospite /*
1087bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1088bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1089bd28ce00SJiri Slaby  * events.
1090bd28ce00SJiri Slaby  */
1091816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1092bd28ce00SJiri Slaby {
1093bd28ce00SJiri Slaby 	int ret;
1094bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
1095bd28ce00SJiri Slaby 
1096bd28ce00SJiri Slaby 	if (!buf)
1097bd28ce00SJiri Slaby 		return -ENOMEM;
1098bd28ce00SJiri Slaby 
1099cafebc05SBenjamin Tissoires 	ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
1100cafebc05SBenjamin Tissoires 				 HID_REQ_GET_REPORT);
1101f204828aSBenjamin Tissoires 
1102bd28ce00SJiri Slaby 	if (ret < 0)
11034291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
1104bd28ce00SJiri Slaby 
1105bd28ce00SJiri Slaby 	kfree(buf);
1106bd28ce00SJiri Slaby 
1107bd28ce00SJiri Slaby 	return ret;
1108bd28ce00SJiri Slaby }
1109bd28ce00SJiri Slaby 
1110816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1111f9ce7c28SBastien Nocera {
1112fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
1113b0dd72aaSBenjamin Tissoires 	return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
1114b0dd72aaSBenjamin Tissoires 				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
1115f9ce7c28SBastien Nocera }
1116f9ce7c28SBastien Nocera 
1117ad142b9eSFrank Praznik /*
1118ad142b9eSFrank Praznik  * Requesting feature report 0x02 in Bluetooth mode changes the state of the
111968330d83SFrank Praznik  * controller so that it sends full input reports of type 0x11.
112068330d83SFrank Praznik  */
112168330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev)
112268330d83SFrank Praznik {
112368330d83SFrank Praznik 	__u8 buf[37] = { 0 };
112468330d83SFrank Praznik 
112568330d83SFrank Praznik 	return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),
112668330d83SFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1127bd28ce00SJiri Slaby }
1128bd28ce00SJiri Slaby 
11298025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS])
11308025087aSFrank Praznik {
11318025087aSFrank Praznik 	static const __u8 sixaxis_leds[10][4] = {
11328025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x00 },
11338025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x00 },
11348025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x00 },
11358025087aSFrank Praznik 				{ 0x00, 0x00, 0x00, 0x01 },
11368025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x01 },
11378025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x01 },
11388025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x01 },
11398025087aSFrank Praznik 				{ 0x01, 0x00, 0x01, 0x01 },
11408025087aSFrank Praznik 				{ 0x00, 0x01, 0x01, 0x01 },
11418025087aSFrank Praznik 				{ 0x01, 0x01, 0x01, 0x01 }
11428025087aSFrank Praznik 	};
11438025087aSFrank Praznik 
11448025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
11458025087aSFrank Praznik 
11468025087aSFrank Praznik 	if (id < 0)
11478025087aSFrank Praznik 		return;
11488025087aSFrank Praznik 
11498025087aSFrank Praznik 	id %= 10;
11508025087aSFrank Praznik 	memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
11518025087aSFrank Praznik }
11528025087aSFrank Praznik 
11538025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS])
11548025087aSFrank Praznik {
11558025087aSFrank Praznik 	/* The first 4 color/index entries match what the PS4 assigns */
11568025087aSFrank Praznik 	static const __u8 color_code[7][3] = {
11578025087aSFrank Praznik 			/* Blue   */	{ 0x00, 0x00, 0x01 },
11588025087aSFrank Praznik 			/* Red	  */	{ 0x01, 0x00, 0x00 },
11598025087aSFrank Praznik 			/* Green  */	{ 0x00, 0x01, 0x00 },
11608025087aSFrank Praznik 			/* Pink   */	{ 0x02, 0x00, 0x01 },
11618025087aSFrank Praznik 			/* Orange */	{ 0x02, 0x01, 0x00 },
11628025087aSFrank Praznik 			/* Teal   */	{ 0x00, 0x01, 0x01 },
11638025087aSFrank Praznik 			/* White  */	{ 0x01, 0x01, 0x01 }
11648025087aSFrank Praznik 	};
11658025087aSFrank Praznik 
11668025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
11678025087aSFrank Praznik 
11688025087aSFrank Praznik 	if (id < 0)
11698025087aSFrank Praznik 		return;
11708025087aSFrank Praznik 
11718025087aSFrank Praznik 	id %= 7;
11728025087aSFrank Praznik 	memcpy(values, color_code[id], sizeof(color_code[id]));
11738025087aSFrank Praznik }
11748025087aSFrank Praznik 
117560781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
1176f04d5140SColin Leitner {
1177f04d5140SColin Leitner 	struct list_head *report_list =
1178f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1179f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1180f04d5140SColin Leitner 		struct hid_report, list);
1181f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
1182f04d5140SColin Leitner 
1183f04d5140SColin Leitner 	value[0] = 0x00;
118460781cf4SFrank Praznik 	value[1] = leds[0] ? 0xff : 0x00;
118560781cf4SFrank Praznik 	value[2] = leds[1] ? 0xff : 0x00;
118660781cf4SFrank Praznik 	value[3] = leds[2] ? 0xff : 0x00;
118760781cf4SFrank Praznik 	value[4] = leds[3] ? 0xff : 0x00;
1188f04d5140SColin Leitner 	value[5] = 0x00;
1189f04d5140SColin Leitner 	value[6] = 0x00;
1190f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1191f04d5140SColin Leitner }
1192f04d5140SColin Leitner 
1193fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count)
11940a286ef2SSven Eckelmann {
119560781cf4SFrank Praznik 	int n;
11960a286ef2SSven Eckelmann 
119760781cf4SFrank Praznik 	BUG_ON(count > MAX_LEDS);
119860781cf4SFrank Praznik 
1199fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER && count == 4) {
1200fa57a810SFrank Praznik 		buzz_set_leds(sc->hdev, leds);
1201fee4e2d5SFrank Praznik 	} else {
120260781cf4SFrank Praznik 		for (n = 0; n < count; n++)
1203fa57a810SFrank Praznik 			sc->led_state[n] = leds[n];
1204fa57a810SFrank Praznik 		schedule_work(&sc->state_worker);
12050a286ef2SSven Eckelmann 	}
12060a286ef2SSven Eckelmann }
12070a286ef2SSven Eckelmann 
1208c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1209f04d5140SColin Leitner 				    enum led_brightness value)
1210f04d5140SColin Leitner {
1211f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1212f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1213f04d5140SColin Leitner 	struct sony_sc *drv_data;
1214f04d5140SColin Leitner 
1215f04d5140SColin Leitner 	int n;
1216b3ed458cSFrank Praznik 	int force_update;
1217f04d5140SColin Leitner 
1218f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12192251b85fSSven Eckelmann 	if (!drv_data) {
1220f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1221f04d5140SColin Leitner 		return;
1222f04d5140SColin Leitner 	}
1223f04d5140SColin Leitner 
1224b3ed458cSFrank Praznik 	/*
1225b3ed458cSFrank Praznik 	 * The Sixaxis on USB will override any LED settings sent to it
1226b3ed458cSFrank Praznik 	 * and keep flashing all of the LEDs until the PS button is pressed.
1227b3ed458cSFrank Praznik 	 * Updates, even if redundant, must be always be sent to the
1228b3ed458cSFrank Praznik 	 * controller to avoid having to toggle the state of an LED just to
1229b3ed458cSFrank Praznik 	 * stop the flashing later on.
1230b3ed458cSFrank Praznik 	 */
1231b3ed458cSFrank Praznik 	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1232b3ed458cSFrank Praznik 
123360781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1234b3ed458cSFrank Praznik 		if (led == drv_data->leds[n] && (force_update ||
1235b3ed458cSFrank Praznik 			(value != drv_data->led_state[n] ||
1236b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] ||
1237b3ed458cSFrank Praznik 			drv_data->led_delay_off[n]))) {
1238b3ed458cSFrank Praznik 
123960781cf4SFrank Praznik 			drv_data->led_state[n] = value;
1240b3ed458cSFrank Praznik 
1241b3ed458cSFrank Praznik 			/* Setting the brightness stops the blinking */
1242b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] = 0;
1243b3ed458cSFrank Praznik 			drv_data->led_delay_off[n] = 0;
1244b3ed458cSFrank Praznik 
1245fa57a810SFrank Praznik 			sony_set_leds(drv_data, drv_data->led_state,
1246fa57a810SFrank Praznik 					drv_data->led_count);
1247f04d5140SColin Leitner 			break;
1248f04d5140SColin Leitner 		}
1249f04d5140SColin Leitner 	}
1250f04d5140SColin Leitner }
1251f04d5140SColin Leitner 
1252c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1253f04d5140SColin Leitner {
1254f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1255f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1256f04d5140SColin Leitner 	struct sony_sc *drv_data;
1257f04d5140SColin Leitner 
1258f04d5140SColin Leitner 	int n;
1259f04d5140SColin Leitner 
1260f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12612251b85fSSven Eckelmann 	if (!drv_data) {
1262f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1263f04d5140SColin Leitner 		return LED_OFF;
1264f04d5140SColin Leitner 	}
1265f04d5140SColin Leitner 
126660781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
12677db7504aSSimon Wood 		if (led == drv_data->leds[n])
12687db7504aSSimon Wood 			return drv_data->led_state[n];
1269f04d5140SColin Leitner 	}
1270f04d5140SColin Leitner 
12717db7504aSSimon Wood 	return LED_OFF;
1272f04d5140SColin Leitner }
1273f04d5140SColin Leitner 
1274b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1275b3ed458cSFrank Praznik 				unsigned long *delay_off)
1276b3ed458cSFrank Praznik {
1277b3ed458cSFrank Praznik 	struct device *dev = led->dev->parent;
1278b3ed458cSFrank Praznik 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1279b3ed458cSFrank Praznik 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
1280b3ed458cSFrank Praznik 	int n;
1281b3ed458cSFrank Praznik 	__u8 new_on, new_off;
1282b3ed458cSFrank Praznik 
1283b3ed458cSFrank Praznik 	if (!drv_data) {
1284b3ed458cSFrank Praznik 		hid_err(hdev, "No device data\n");
1285b3ed458cSFrank Praznik 		return -EINVAL;
1286b3ed458cSFrank Praznik 	}
1287b3ed458cSFrank Praznik 
1288b3ed458cSFrank Praznik 	/* Max delay is 255 deciseconds or 2550 milliseconds */
1289b3ed458cSFrank Praznik 	if (*delay_on > 2550)
1290b3ed458cSFrank Praznik 		*delay_on = 2550;
1291b3ed458cSFrank Praznik 	if (*delay_off > 2550)
1292b3ed458cSFrank Praznik 		*delay_off = 2550;
1293b3ed458cSFrank Praznik 
1294b3ed458cSFrank Praznik 	/* Blink at 1 Hz if both values are zero */
1295b3ed458cSFrank Praznik 	if (!*delay_on && !*delay_off)
1296b3ed458cSFrank Praznik 		*delay_on = *delay_off = 500;
1297b3ed458cSFrank Praznik 
1298b3ed458cSFrank Praznik 	new_on = *delay_on / 10;
1299b3ed458cSFrank Praznik 	new_off = *delay_off / 10;
1300b3ed458cSFrank Praznik 
1301b3ed458cSFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1302b3ed458cSFrank Praznik 		if (led == drv_data->leds[n])
1303b3ed458cSFrank Praznik 			break;
1304b3ed458cSFrank Praznik 	}
1305b3ed458cSFrank Praznik 
1306b3ed458cSFrank Praznik 	/* This LED is not registered on this device */
1307b3ed458cSFrank Praznik 	if (n >= drv_data->led_count)
1308b3ed458cSFrank Praznik 		return -EINVAL;
1309b3ed458cSFrank Praznik 
1310b3ed458cSFrank Praznik 	/* Don't schedule work if the values didn't change */
1311b3ed458cSFrank Praznik 	if (new_on != drv_data->led_delay_on[n] ||
1312b3ed458cSFrank Praznik 		new_off != drv_data->led_delay_off[n]) {
1313b3ed458cSFrank Praznik 		drv_data->led_delay_on[n] = new_on;
1314b3ed458cSFrank Praznik 		drv_data->led_delay_off[n] = new_off;
1315b3ed458cSFrank Praznik 		schedule_work(&drv_data->state_worker);
1316b3ed458cSFrank Praznik 	}
1317b3ed458cSFrank Praznik 
1318b3ed458cSFrank Praznik 	return 0;
1319b3ed458cSFrank Praznik }
1320b3ed458cSFrank Praznik 
1321fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc)
13220a286ef2SSven Eckelmann {
13230a286ef2SSven Eckelmann 	struct led_classdev *led;
13240a286ef2SSven Eckelmann 	int n;
13250a286ef2SSven Eckelmann 
1326fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
13270a286ef2SSven Eckelmann 
1328fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
1329fa57a810SFrank Praznik 		led = sc->leds[n];
1330fa57a810SFrank Praznik 		sc->leds[n] = NULL;
13310a286ef2SSven Eckelmann 		if (!led)
13320a286ef2SSven Eckelmann 			continue;
13330a286ef2SSven Eckelmann 		led_classdev_unregister(led);
13340a286ef2SSven Eckelmann 		kfree(led);
13350a286ef2SSven Eckelmann 	}
133660781cf4SFrank Praznik 
1337fa57a810SFrank Praznik 	sc->led_count = 0;
13380a286ef2SSven Eckelmann }
13390a286ef2SSven Eckelmann 
1340fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc)
1341f04d5140SColin Leitner {
1342fa57a810SFrank Praznik 	struct hid_device *hdev = sc->hdev;
134340e32ee6SJiri Kosina 	int n, ret = 0;
1344b3ed458cSFrank Praznik 	int use_ds4_names;
134540e32ee6SJiri Kosina 	struct led_classdev *led;
134640e32ee6SJiri Kosina 	size_t name_sz;
134740e32ee6SJiri Kosina 	char *name;
13480a286ef2SSven Eckelmann 	size_t name_len;
13490a286ef2SSven Eckelmann 	const char *name_fmt;
1350b3ed458cSFrank Praznik 	static const char * const ds4_name_str[] = { "red", "green", "blue",
1351b3ed458cSFrank Praznik 						  "global" };
13528025087aSFrank Praznik 	__u8 initial_values[MAX_LEDS] = { 0 };
13535607c89aSFrank Praznik 	__u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
1354b3ed458cSFrank Praznik 	__u8 use_hw_blink[MAX_LEDS] = { 0 };
1355f04d5140SColin Leitner 
1356fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1357f04d5140SColin Leitner 
1358fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER) {
1359fa57a810SFrank Praznik 		sc->led_count = 4;
1360b3ed458cSFrank Praznik 		use_ds4_names = 0;
13610a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
13620a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
13639446edb9SKees Cook 		/* Validate expected report characteristics. */
13649446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
13659446edb9SKees Cook 			return -ENODEV;
1366fa57a810SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
13678025087aSFrank Praznik 		dualshock4_set_leds_from_id(sc->device_id, initial_values);
1368b3ed458cSFrank Praznik 		initial_values[3] = 1;
1369b3ed458cSFrank Praznik 		sc->led_count = 4;
1370b3ed458cSFrank Praznik 		memset(max_brightness, 255, 3);
1371b3ed458cSFrank Praznik 		use_hw_blink[3] = 1;
1372b3ed458cSFrank Praznik 		use_ds4_names = 1;
137361ebca93SFrank Praznik 		name_len = 0;
137461ebca93SFrank Praznik 		name_fmt = "%s:%s";
137560781cf4SFrank Praznik 	} else {
13768025087aSFrank Praznik 		sixaxis_set_leds_from_id(sc->device_id, initial_values);
1377fa57a810SFrank Praznik 		sc->led_count = 4;
1378b3ed458cSFrank Praznik 		memset(use_hw_blink, 1, 4);
1379b3ed458cSFrank Praznik 		use_ds4_names = 0;
138061ebca93SFrank Praznik 		name_len = strlen("::sony#");
138161ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
138260781cf4SFrank Praznik 	}
138360781cf4SFrank Praznik 
1384ad142b9eSFrank Praznik 	/*
1385ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1386f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1387ad142b9eSFrank Praznik 	 * LEDs to on
1388ad142b9eSFrank Praznik 	 */
1389fa57a810SFrank Praznik 	sony_set_leds(sc, initial_values, sc->led_count);
1390f04d5140SColin Leitner 
13910a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1392f04d5140SColin Leitner 
1393fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
139461ebca93SFrank Praznik 
1395b3ed458cSFrank Praznik 		if (use_ds4_names)
1396b3ed458cSFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
139761ebca93SFrank Praznik 
1398f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1399f04d5140SColin Leitner 		if (!led) {
1400f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
14018cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1402f04d5140SColin Leitner 			goto error_leds;
1403f04d5140SColin Leitner 		}
1404f04d5140SColin Leitner 
1405f04d5140SColin Leitner 		name = (void *)(&led[1]);
1406b3ed458cSFrank Praznik 		if (use_ds4_names)
1407b3ed458cSFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1408b3ed458cSFrank Praznik 			ds4_name_str[n]);
140961ebca93SFrank Praznik 		else
14100a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1411f04d5140SColin Leitner 		led->name = name;
14128025087aSFrank Praznik 		led->brightness = initial_values[n];
1413b3ed458cSFrank Praznik 		led->max_brightness = max_brightness[n];
1414c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1415c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1416f04d5140SColin Leitner 
1417b3ed458cSFrank Praznik 		if (use_hw_blink[n])
1418b3ed458cSFrank Praznik 			led->blink_set = sony_led_blink_set;
1419b3ed458cSFrank Praznik 
14208025087aSFrank Praznik 		sc->leds[n] = led;
14218025087aSFrank Praznik 
14228cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
14238cd5fcdaSJulia Lawall 		if (ret) {
1424f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
14258025087aSFrank Praznik 			sc->leds[n] = NULL;
1426f04d5140SColin Leitner 			kfree(led);
1427f04d5140SColin Leitner 			goto error_leds;
1428f04d5140SColin Leitner 		}
1429f04d5140SColin Leitner 	}
1430f04d5140SColin Leitner 
1431f04d5140SColin Leitner 	return ret;
1432f04d5140SColin Leitner 
1433f04d5140SColin Leitner error_leds:
1434fa57a810SFrank Praznik 	sony_leds_remove(sc);
1435f04d5140SColin Leitner 
1436f04d5140SColin Leitner 	return ret;
1437f04d5140SColin Leitner }
1438f04d5140SColin Leitner 
1439cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
1440a08c22c0SSven Eckelmann {
144192b5c411SSven Eckelmann 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1442b3ed458cSFrank Praznik 	int n;
144355d3b664SFrank Praznik 	union sixaxis_output_report_01 report = {
144455d3b664SFrank Praznik 		.buf = {
1445a08c22c0SSven Eckelmann 			0x01,
1446a08c22c0SSven Eckelmann 			0x00, 0xff, 0x00, 0xff, 0x00,
14470a286ef2SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00,
1448a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1449a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1450a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1451a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1452a08c22c0SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00
145355d3b664SFrank Praznik 		}
1454a08c22c0SSven Eckelmann 	};
14559f323b68SSven Eckelmann 
14560a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
145755d3b664SFrank Praznik 	report.data.rumble.right_motor_on = sc->right ? 1 : 0;
145855d3b664SFrank Praznik 	report.data.rumble.left_motor_force = sc->left;
14590a286ef2SSven Eckelmann #endif
14600a286ef2SSven Eckelmann 
146155d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[0] << 1;
146255d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[1] << 2;
146355d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[2] << 3;
146455d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[3] << 4;
14659f323b68SSven Eckelmann 
146688f6576fSSimon Wood 	/* Set flag for all leds off, required for 3rd party INTEC controller */
146788f6576fSSimon Wood 	if ((report.data.leds_bitmap & 0x1E) == 0)
146888f6576fSSimon Wood 		report.data.leds_bitmap |= 0x20;
146988f6576fSSimon Wood 
1470b3ed458cSFrank Praznik 	/*
1471b3ed458cSFrank Praznik 	 * The LEDs in the report are indexed in reverse order to their
1472b3ed458cSFrank Praznik 	 * corresponding light on the controller.
1473b3ed458cSFrank Praznik 	 * Index 0 = LED 4, index 1 = LED 3, etc...
1474b3ed458cSFrank Praznik 	 *
1475b3ed458cSFrank Praznik 	 * In the case of both delay values being zero (blinking disabled) the
1476b3ed458cSFrank Praznik 	 * default report values should be used or the controller LED will be
1477b3ed458cSFrank Praznik 	 * always off.
1478b3ed458cSFrank Praznik 	 */
1479b3ed458cSFrank Praznik 	for (n = 0; n < 4; n++) {
1480b3ed458cSFrank Praznik 		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
1481b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_off = sc->led_delay_off[n];
1482b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_on = sc->led_delay_on[n];
1483b3ed458cSFrank Praznik 		}
1484b3ed458cSFrank Praznik 	}
1485b3ed458cSFrank Praznik 
148655d3b664SFrank Praznik 	hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
148755d3b664SFrank Praznik 			sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
14889f323b68SSven Eckelmann }
14899f323b68SSven Eckelmann 
14900bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
14910bd88dd3SFrank Praznik {
14920bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
14930da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
149448220237SFrank Praznik 	int offset;
14950da8ea65SFrank Praznik 
1496fdcf105dSFrank Praznik 	__u8 buf[78] = { 0 };
149748220237SFrank Praznik 
1498fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
149948220237SFrank Praznik 		buf[0] = 0x05;
1500b3ed458cSFrank Praznik 		buf[1] = 0xFF;
150148220237SFrank Praznik 		offset = 4;
1502fdcf105dSFrank Praznik 	} else {
1503fdcf105dSFrank Praznik 		buf[0] = 0x11;
1504fdcf105dSFrank Praznik 		buf[1] = 0xB0;
1505fdcf105dSFrank Praznik 		buf[3] = 0x0F;
1506fdcf105dSFrank Praznik 		offset = 6;
1507fdcf105dSFrank Praznik 	}
15080bd88dd3SFrank Praznik 
15090bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
151048220237SFrank Praznik 	buf[offset++] = sc->right;
151148220237SFrank Praznik 	buf[offset++] = sc->left;
151248220237SFrank Praznik #else
151348220237SFrank Praznik 	offset += 2;
15140bd88dd3SFrank Praznik #endif
15150bd88dd3SFrank Praznik 
1516b3ed458cSFrank Praznik 	/* LED 3 is the global control */
1517b3ed458cSFrank Praznik 	if (sc->led_state[3]) {
151848220237SFrank Praznik 		buf[offset++] = sc->led_state[0];
151948220237SFrank Praznik 		buf[offset++] = sc->led_state[1];
152048220237SFrank Praznik 		buf[offset++] = sc->led_state[2];
1521b3ed458cSFrank Praznik 	} else {
1522b3ed458cSFrank Praznik 		offset += 3;
1523b3ed458cSFrank Praznik 	}
1524b3ed458cSFrank Praznik 
1525b3ed458cSFrank Praznik 	/* If both delay values are zero the DualShock 4 disables blinking. */
1526b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_on[3];
1527b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_off[3];
152860781cf4SFrank Praznik 
1529fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1530fdcf105dSFrank Praznik 		hid_hw_output_report(hdev, buf, 32);
1531fdcf105dSFrank Praznik 	else
1532fdcf105dSFrank Praznik 		hid_hw_raw_request(hdev, 0x11, buf, 78,
1533fdcf105dSFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
15340bd88dd3SFrank Praznik }
15350bd88dd3SFrank Praznik 
15360a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
15379f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
15389f323b68SSven Eckelmann 			    struct ff_effect *effect)
15399f323b68SSven Eckelmann {
1540a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
15419f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
1542a08c22c0SSven Eckelmann 
1543a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
1544a08c22c0SSven Eckelmann 		return 0;
1545a08c22c0SSven Eckelmann 
15469f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
15470bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
1548a08c22c0SSven Eckelmann 
154992b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
15509f323b68SSven Eckelmann 	return 0;
1551a08c22c0SSven Eckelmann }
1552a08c22c0SSven Eckelmann 
1553fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1554a08c22c0SSven Eckelmann {
1555fa57a810SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1556a08c22c0SSven Eckelmann 						struct hid_input, list);
1557a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
1558a08c22c0SSven Eckelmann 
1559a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1560a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1561a08c22c0SSven Eckelmann }
1562a08c22c0SSven Eckelmann 
1563a08c22c0SSven Eckelmann #else
1564fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1565a08c22c0SSven Eckelmann {
1566a08c22c0SSven Eckelmann 	return 0;
1567a08c22c0SSven Eckelmann }
15689f323b68SSven Eckelmann 
1569a08c22c0SSven Eckelmann #endif
1570a08c22c0SSven Eckelmann 
1571d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
1572d902f472SFrank Praznik 				     enum power_supply_property psp,
1573d902f472SFrank Praznik 				     union power_supply_propval *val)
1574c4e1ddf2SFrank Praznik {
1575d902f472SFrank Praznik 	struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
1576d902f472SFrank Praznik 	unsigned long flags;
1577d902f472SFrank Praznik 	int ret = 0;
1578d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
1579c4e1ddf2SFrank Praznik 
1580d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1581d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
1582d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
1583d902f472SFrank Praznik 	cable_state = sc->cable_state;
1584d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1585c4e1ddf2SFrank Praznik 
1586d902f472SFrank Praznik 	switch (psp) {
1587d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
1588d902f472SFrank Praznik 		val->intval = 1;
1589d902f472SFrank Praznik 		break;
1590d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
1591d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1592d902f472SFrank Praznik 		break;
1593d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
1594d902f472SFrank Praznik 		val->intval = battery_capacity;
1595d902f472SFrank Praznik 		break;
1596d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
1597d902f472SFrank Praznik 		if (battery_charging)
1598d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
1599d902f472SFrank Praznik 		else
1600d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
1601d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
1602d902f472SFrank Praznik 			else
1603d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1604d902f472SFrank Praznik 		break;
1605d902f472SFrank Praznik 	default:
1606d902f472SFrank Praznik 		ret = -EINVAL;
1607d902f472SFrank Praznik 		break;
1608c4e1ddf2SFrank Praznik 	}
1609d902f472SFrank Praznik 	return ret;
1610d902f472SFrank Praznik }
1611d902f472SFrank Praznik 
1612d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc)
1613d902f472SFrank Praznik {
1614d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1615d902f472SFrank Praznik 	int ret;
1616d902f472SFrank Praznik 
1617ad142b9eSFrank Praznik 	/*
1618ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
1619d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
1620d9a293a9SFrank Praznik 	 */
1621d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
1622d9a293a9SFrank Praznik 
1623d902f472SFrank Praznik 	sc->battery.properties = sony_battery_props;
1624d902f472SFrank Praznik 	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
1625d902f472SFrank Praznik 	sc->battery.get_property = sony_battery_get_property;
1626d902f472SFrank Praznik 	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1627d902f472SFrank Praznik 	sc->battery.use_for_apm = 0;
1628314531f1SFrank Praznik 	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR",
1629314531f1SFrank Praznik 				     sc->mac_address);
1630d902f472SFrank Praznik 	if (!sc->battery.name)
1631d902f472SFrank Praznik 		return -ENOMEM;
1632d902f472SFrank Praznik 
1633d902f472SFrank Praznik 	ret = power_supply_register(&hdev->dev, &sc->battery);
1634d902f472SFrank Praznik 	if (ret) {
1635d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
1636d902f472SFrank Praznik 		goto err_free;
1637d902f472SFrank Praznik 	}
1638d902f472SFrank Praznik 
1639d902f472SFrank Praznik 	power_supply_powers(&sc->battery, &hdev->dev);
1640d902f472SFrank Praznik 	return 0;
1641d902f472SFrank Praznik 
1642d902f472SFrank Praznik err_free:
1643d902f472SFrank Praznik 	kfree(sc->battery.name);
1644d902f472SFrank Praznik 	sc->battery.name = NULL;
1645d902f472SFrank Praznik 	return ret;
1646d902f472SFrank Praznik }
1647d902f472SFrank Praznik 
1648d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
1649d902f472SFrank Praznik {
1650d902f472SFrank Praznik 	if (!sc->battery.name)
1651d902f472SFrank Praznik 		return;
1652d902f472SFrank Praznik 
1653d902f472SFrank Praznik 	power_supply_unregister(&sc->battery);
1654d902f472SFrank Praznik 	kfree(sc->battery.name);
1655d902f472SFrank Praznik 	sc->battery.name = NULL;
1656d902f472SFrank Praznik }
1657d902f472SFrank Praznik 
1658e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1659e5606230SFrank Praznik 					int w, int h)
1660e5606230SFrank Praznik {
1661e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1662e5606230SFrank Praznik 						struct hid_input, list);
1663e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
1664e5606230SFrank Praznik 	int ret;
1665e5606230SFrank Praznik 
1666e5606230SFrank Praznik 	ret = input_mt_init_slots(input_dev, touch_count, 0);
1667e5606230SFrank Praznik 	if (ret < 0) {
1668e5606230SFrank Praznik 		hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
1669e5606230SFrank Praznik 		return ret;
1670e5606230SFrank Praznik 	}
1671e5606230SFrank Praznik 
1672e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1673e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1674e5606230SFrank Praznik 
1675c4e1ddf2SFrank Praznik 	return 0;
1676c4e1ddf2SFrank Praznik }
1677e5606230SFrank Praznik 
1678d2d782fcSFrank Praznik /*
1679d2d782fcSFrank Praznik  * If a controller is plugged in via USB while already connected via Bluetooth
1680d2d782fcSFrank Praznik  * it will show up as two devices. A global list of connected controllers and
1681d2d782fcSFrank Praznik  * their MAC addresses is maintained to ensure that a device is only connected
1682d2d782fcSFrank Praznik  * once.
1683d2d782fcSFrank Praznik  */
1684d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc)
1685d2d782fcSFrank Praznik {
1686d2d782fcSFrank Praznik 	struct sony_sc *entry;
1687d2d782fcSFrank Praznik 	unsigned long flags;
1688d2d782fcSFrank Praznik 	int ret;
1689d2d782fcSFrank Praznik 
1690d2d782fcSFrank Praznik 	spin_lock_irqsave(&sony_dev_list_lock, flags);
1691d2d782fcSFrank Praznik 
1692d2d782fcSFrank Praznik 	list_for_each_entry(entry, &sony_device_list, list_node) {
1693d2d782fcSFrank Praznik 		ret = memcmp(sc->mac_address, entry->mac_address,
1694d2d782fcSFrank Praznik 				sizeof(sc->mac_address));
1695d2d782fcSFrank Praznik 		if (!ret) {
1696d2d782fcSFrank Praznik 			ret = -EEXIST;
1697d2d782fcSFrank Praznik 			hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",
1698d2d782fcSFrank Praznik 				sc->mac_address);
1699d2d782fcSFrank Praznik 			goto unlock;
1700d2d782fcSFrank Praznik 		}
1701c4e1ddf2SFrank Praznik 	}
1702c4e1ddf2SFrank Praznik 
1703d2d782fcSFrank Praznik 	ret = 0;
1704d2d782fcSFrank Praznik 	list_add(&(sc->list_node), &sony_device_list);
1705c4e1ddf2SFrank Praznik 
1706d2d782fcSFrank Praznik unlock:
1707d2d782fcSFrank Praznik 	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1708d2d782fcSFrank Praznik 	return ret;
1709d2d782fcSFrank Praznik }
1710d2d782fcSFrank Praznik 
1711d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc)
1712d2d782fcSFrank Praznik {
1713d2d782fcSFrank Praznik 	unsigned long flags;
1714d2d782fcSFrank Praznik 
1715d2d782fcSFrank Praznik 	if (sc->list_node.next) {
1716d2d782fcSFrank Praznik 		spin_lock_irqsave(&sony_dev_list_lock, flags);
1717d2d782fcSFrank Praznik 		list_del(&(sc->list_node));
1718d2d782fcSFrank Praznik 		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1719d2d782fcSFrank Praznik 	}
1720d2d782fcSFrank Praznik }
1721d2d782fcSFrank Praznik 
1722d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc)
1723d2d782fcSFrank Praznik {
1724d2d782fcSFrank Praznik 	int ret;
1725d2d782fcSFrank Praznik 
1726d2d782fcSFrank Praznik 	/* HIDP stores the device MAC address as a string in the uniq field. */
1727d2d782fcSFrank Praznik 	ret = strlen(sc->hdev->uniq);
1728d2d782fcSFrank Praznik 	if (ret != 17)
1729c4e1ddf2SFrank Praznik 		return -EINVAL;
1730d2d782fcSFrank Praznik 
1731d2d782fcSFrank Praznik 	ret = sscanf(sc->hdev->uniq,
1732d2d782fcSFrank Praznik 		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1733d2d782fcSFrank Praznik 		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
1734d2d782fcSFrank Praznik 		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
1735d2d782fcSFrank Praznik 
1736d2d782fcSFrank Praznik 	if (ret != 6)
1737d2d782fcSFrank Praznik 		return -EINVAL;
1738d2d782fcSFrank Praznik 
1739d2d782fcSFrank Praznik 	return 0;
1740c4e1ddf2SFrank Praznik }
1741c4e1ddf2SFrank Praznik 
1742d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc)
1743d2d782fcSFrank Praznik {
1744d2d782fcSFrank Praznik 	int n, ret;
1745d2d782fcSFrank Praznik 
1746d2d782fcSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
1747d2d782fcSFrank Praznik 	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
1748d2d782fcSFrank Praznik 		/*
1749d2d782fcSFrank Praznik 		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
1750d2d782fcSFrank Praznik 		 * address from the uniq string where HIDP stores it.
1751d2d782fcSFrank Praznik 		 * As uniq cannot be guaranteed to be a MAC address in all cases
1752d2d782fcSFrank Praznik 		 * a failure of this function should not prevent the connection.
1753d2d782fcSFrank Praznik 		 */
1754d2d782fcSFrank Praznik 		if (sony_get_bt_devaddr(sc) < 0) {
1755d2d782fcSFrank Praznik 			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");
1756d2d782fcSFrank Praznik 			return 0;
1757d2d782fcSFrank Praznik 		}
1758d2d782fcSFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
1759d2d782fcSFrank Praznik 		__u8 buf[7];
1760d2d782fcSFrank Praznik 
1761d2d782fcSFrank Praznik 		/*
1762d2d782fcSFrank Praznik 		 * The MAC address of a DS4 controller connected via USB can be
1763d2d782fcSFrank Praznik 		 * retrieved with feature report 0x81. The address begins at
1764d2d782fcSFrank Praznik 		 * offset 1.
1765d2d782fcSFrank Praznik 		 */
1766d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf),
1767d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1768d2d782fcSFrank Praznik 
1769d2d782fcSFrank Praznik 		if (ret != 7) {
1770d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
1771d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1772d2d782fcSFrank Praznik 		}
1773d2d782fcSFrank Praznik 
1774d2d782fcSFrank Praznik 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
1775d2d782fcSFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1776d2d782fcSFrank Praznik 		__u8 buf[18];
1777d2d782fcSFrank Praznik 
1778d2d782fcSFrank Praznik 		/*
1779d2d782fcSFrank Praznik 		 * The MAC address of a Sixaxis controller connected via USB can
1780d2d782fcSFrank Praznik 		 * be retrieved with feature report 0xf2. The address begins at
1781d2d782fcSFrank Praznik 		 * offset 4.
1782d2d782fcSFrank Praznik 		 */
1783d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf),
1784d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1785d2d782fcSFrank Praznik 
1786d2d782fcSFrank Praznik 		if (ret != 18) {
1787d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");
1788d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1789d2d782fcSFrank Praznik 		}
1790d2d782fcSFrank Praznik 
1791d2d782fcSFrank Praznik 		/*
1792d2d782fcSFrank Praznik 		 * The Sixaxis device MAC in the report is big-endian and must
1793d2d782fcSFrank Praznik 		 * be byte-swapped.
1794d2d782fcSFrank Praznik 		 */
1795d2d782fcSFrank Praznik 		for (n = 0; n < 6; n++)
1796d2d782fcSFrank Praznik 			sc->mac_address[5-n] = buf[4+n];
1797d2d782fcSFrank Praznik 	} else {
1798d2d782fcSFrank Praznik 		return 0;
1799d2d782fcSFrank Praznik 	}
1800d2d782fcSFrank Praznik 
1801d2d782fcSFrank Praznik 	return sony_check_add_dev_list(sc);
1802d2d782fcSFrank Praznik }
1803d2d782fcSFrank Praznik 
18048025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc)
18058025087aSFrank Praznik {
18068025087aSFrank Praznik 	int ret;
18078025087aSFrank Praznik 
18088025087aSFrank Praznik 	/*
18098025087aSFrank Praznik 	 * Only DualShock 4 or Sixaxis controllers get an id.
18108025087aSFrank Praznik 	 * All others are set to -1.
18118025087aSFrank Praznik 	 */
18128025087aSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
18138025087aSFrank Praznik 	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
18148025087aSFrank Praznik 		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
18158025087aSFrank Praznik 					GFP_KERNEL);
18168025087aSFrank Praznik 		if (ret < 0) {
18178025087aSFrank Praznik 			sc->device_id = -1;
18188025087aSFrank Praznik 			return ret;
18198025087aSFrank Praznik 		}
18208025087aSFrank Praznik 		sc->device_id = ret;
18218025087aSFrank Praznik 	} else {
18228025087aSFrank Praznik 		sc->device_id = -1;
18238025087aSFrank Praznik 	}
18248025087aSFrank Praznik 
18258025087aSFrank Praznik 	return 0;
18268025087aSFrank Praznik }
18278025087aSFrank Praznik 
18288025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc)
18298025087aSFrank Praznik {
18308025087aSFrank Praznik 	if (sc->device_id >= 0) {
18318025087aSFrank Praznik 		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
18328025087aSFrank Praznik 		sc->device_id = -1;
18338025087aSFrank Praznik 	}
18348025087aSFrank Praznik }
18358025087aSFrank Praznik 
183646262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc,
183746262047SFrank Praznik 					void (*worker)(struct work_struct *))
183846262047SFrank Praznik {
183946262047SFrank Praznik 	if (!sc->worker_initialized)
184046262047SFrank Praznik 		INIT_WORK(&sc->state_worker, worker);
184146262047SFrank Praznik 
184246262047SFrank Praznik 	sc->worker_initialized = 1;
184346262047SFrank Praznik }
184446262047SFrank Praznik 
184546262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc)
184646262047SFrank Praznik {
184746262047SFrank Praznik 	if (sc->worker_initialized)
184846262047SFrank Praznik 		cancel_work_sync(&sc->state_worker);
184946262047SFrank Praznik }
1850d2d782fcSFrank Praznik 
1851bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1852bd28ce00SJiri Slaby {
1853bd28ce00SJiri Slaby 	int ret;
1854cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
1855cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
1856f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
1857cc6e0bbbSJiri Kosina 
1858abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
1859cc6e0bbbSJiri Kosina 	if (sc == NULL) {
18604291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
1861cc6e0bbbSJiri Kosina 		return -ENOMEM;
1862cc6e0bbbSJiri Kosina 	}
1863cc6e0bbbSJiri Kosina 
1864cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
1865cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
18660a286ef2SSven Eckelmann 	sc->hdev = hdev;
1867bd28ce00SJiri Slaby 
1868bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
1869bd28ce00SJiri Slaby 	if (ret) {
18704291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
1871abf832bfSBenjamin Tissoires 		return ret;
1872bd28ce00SJiri Slaby 	}
1873bd28ce00SJiri Slaby 
1874f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
1875f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
187650764650SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER)
1877f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1878f04d5140SColin Leitner 
1879f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
1880bd28ce00SJiri Slaby 	if (ret) {
18814291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
1882abf832bfSBenjamin Tissoires 		return ret;
1883bd28ce00SJiri Slaby 	}
1884bd28ce00SJiri Slaby 
18858025087aSFrank Praznik 	ret = sony_set_device_id(sc);
18868025087aSFrank Praznik 	if (ret < 0) {
18878025087aSFrank Praznik 		hid_err(hdev, "failed to allocate the device id\n");
18888025087aSFrank Praznik 		goto err_stop;
18898025087aSFrank Praznik 	}
18908025087aSFrank Praznik 
1891569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1892e534a935SBenjamin Tissoires 		/*
1893e534a935SBenjamin Tissoires 		 * The Sony Sixaxis does not handle HID Output Reports on the
1894e534a935SBenjamin Tissoires 		 * Interrupt EP like it could, so we need to force HID Output
1895e534a935SBenjamin Tissoires 		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
1896e534a935SBenjamin Tissoires 		 *
1897e534a935SBenjamin Tissoires 		 * There is also another issue about HID Output Reports via USB,
1898e534a935SBenjamin Tissoires 		 * the Sixaxis does not want the report_id as part of the data
1899e534a935SBenjamin Tissoires 		 * packet, so we have to discard buf[0] when sending the actual
1900e534a935SBenjamin Tissoires 		 * control message, even for numbered reports, humpf!
1901e534a935SBenjamin Tissoires 		 */
1902e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1903e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
1904816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
190546262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1906fee4e2d5SFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
19072078b9bbSFrank Praznik 		/*
19082078b9bbSFrank Praznik 		 * The Sixaxis wants output reports sent on the ctrl endpoint
19092078b9bbSFrank Praznik 		 * when connected via Bluetooth.
19102078b9bbSFrank Praznik 		 */
19112078b9bbSFrank Praznik 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1912816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
191346262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1914fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
191568330d83SFrank Praznik 		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
19162078b9bbSFrank Praznik 			/*
19172078b9bbSFrank Praznik 			 * The DualShock 4 wants output reports sent on the ctrl
19182078b9bbSFrank Praznik 			 * endpoint when connected via Bluetooth.
19192078b9bbSFrank Praznik 			 */
19202078b9bbSFrank Praznik 			hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
192168330d83SFrank Praznik 			ret = dualshock4_set_operational_bt(hdev);
192268330d83SFrank Praznik 			if (ret < 0) {
192368330d83SFrank Praznik 				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
192468330d83SFrank Praznik 				goto err_stop;
192568330d83SFrank Praznik 			}
192668330d83SFrank Praznik 		}
1927ad142b9eSFrank Praznik 		/*
1928ad142b9eSFrank Praznik 		 * The Dualshock 4 touchpad supports 2 touches and has a
1929e5606230SFrank Praznik 		 * resolution of 1920x940.
1930e5606230SFrank Praznik 		 */
1931e5606230SFrank Praznik 		ret = sony_register_touchpad(sc, 2, 1920, 940);
1932c4e1ddf2SFrank Praznik 		if (ret < 0)
1933c4e1ddf2SFrank Praznik 			goto err_stop;
1934c4e1ddf2SFrank Praznik 
193546262047SFrank Praznik 		sony_init_work(sc, dualshock4_state_worker);
19360bd88dd3SFrank Praznik 	} else {
19370bd88dd3SFrank Praznik 		ret = 0;
19380bd88dd3SFrank Praznik 	}
1939f9ce7c28SBastien Nocera 
19404dfdc464SJiri Kosina 	if (ret < 0)
1941bd28ce00SJiri Slaby 		goto err_stop;
1942bd28ce00SJiri Slaby 
1943d2d782fcSFrank Praznik 	ret = sony_check_add(sc);
1944d2d782fcSFrank Praznik 	if (ret < 0)
1945d2d782fcSFrank Praznik 		goto err_stop;
1946d2d782fcSFrank Praznik 
19470a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
1948fa57a810SFrank Praznik 		ret = sony_leds_init(sc);
19490a286ef2SSven Eckelmann 		if (ret < 0)
19500a286ef2SSven Eckelmann 			goto err_stop;
19510a286ef2SSven Eckelmann 	}
19520a286ef2SSven Eckelmann 
1953d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1954d902f472SFrank Praznik 		ret = sony_battery_probe(sc);
1955a08c22c0SSven Eckelmann 		if (ret < 0)
1956a08c22c0SSven Eckelmann 			goto err_stop;
1957a08c22c0SSven Eckelmann 
1958d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
1959d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
1960d902f472SFrank Praznik 		if (ret < 0) {
1961d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
1962d902f472SFrank Praznik 			goto err_stop;
1963d902f472SFrank Praznik 		}
1964d902f472SFrank Praznik 	}
1965d902f472SFrank Praznik 
1966c8de9dbbSFrank Praznik 	if (sc->quirks & SONY_FF_SUPPORT) {
1967fa57a810SFrank Praznik 		ret = sony_init_ff(sc);
1968d902f472SFrank Praznik 		if (ret < 0)
1969d902f472SFrank Praznik 			goto err_close;
19705f5750d2SFrank Praznik 	}
1971bd28ce00SJiri Slaby 
1972f425458eSH Hartley Sweeten 	return 0;
1973d902f472SFrank Praznik err_close:
1974d902f472SFrank Praznik 	hid_hw_close(hdev);
1975bd28ce00SJiri Slaby err_stop:
19760a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1977fa57a810SFrank Praznik 		sony_leds_remove(sc);
1978d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
1979d902f472SFrank Praznik 		sony_battery_remove(sc);
198046262047SFrank Praznik 	sony_cancel_work_sync(sc);
1981d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
19828025087aSFrank Praznik 	sony_release_device_id(sc);
1983bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
1984bd28ce00SJiri Slaby 	return ret;
1985bd28ce00SJiri Slaby }
1986bd28ce00SJiri Slaby 
1987bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev)
1988bd28ce00SJiri Slaby {
1989bd28ce00SJiri Slaby 	struct sony_sc *sc = hid_get_drvdata(hdev);
1990bd28ce00SJiri Slaby 
19910a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1992fa57a810SFrank Praznik 		sony_leds_remove(sc);
1993bd28ce00SJiri Slaby 
1994d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1995d902f472SFrank Praznik 		hid_hw_close(hdev);
1996d902f472SFrank Praznik 		sony_battery_remove(sc);
1997d902f472SFrank Praznik 	}
1998d902f472SFrank Praznik 
199946262047SFrank Praznik 	sony_cancel_work_sync(sc);
20009f323b68SSven Eckelmann 
2001d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
2002bd28ce00SJiri Slaby 
20038025087aSFrank Praznik 	sony_release_device_id(sc);
20048025087aSFrank Praznik 
2005bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2006bd28ce00SJiri Slaby }
2007bd28ce00SJiri Slaby 
2008bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
2009bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2010bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2011bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
2012bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2013bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2014bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_BT },
2015bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
2016bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2017bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
2018bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2019bd28ce00SJiri Slaby 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
2020bd28ce00SJiri Slaby 	 * Logitech joystick from the device descriptor. */
2021bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
2022bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2023bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
2024bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2025bd28ce00SJiri Slaby 	/* PS3 BD Remote Control */
2026bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
2027bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
2028bd28ce00SJiri Slaby 	/* Logitech Harmony Adapter for PS3 */
2029bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
2030bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
20310bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
20320bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
20338ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
20340bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
20358ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
2036bd28ce00SJiri Slaby 	{ }
2037bd28ce00SJiri Slaby };
2038bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
2039bd28ce00SJiri Slaby 
2040bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
2041bd28ce00SJiri Slaby 	.name          = "sony",
2042bd28ce00SJiri Slaby 	.id_table      = sony_devices,
2043bd28ce00SJiri Slaby 	.input_mapping = sony_mapping,
2044bd28ce00SJiri Slaby 	.probe         = sony_probe,
2045bd28ce00SJiri Slaby 	.remove        = sony_remove,
2046bd28ce00SJiri Slaby 	.report_fixup  = sony_report_fixup,
2047bd28ce00SJiri Slaby 	.raw_event     = sony_raw_event
2048bd28ce00SJiri Slaby };
20498025087aSFrank Praznik 
20508025087aSFrank Praznik static int __init sony_init(void)
20518025087aSFrank Praznik {
20528025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20538025087aSFrank Praznik 
20548025087aSFrank Praznik 	return hid_register_driver(&sony_driver);
20558025087aSFrank Praznik }
20568025087aSFrank Praznik 
20578025087aSFrank Praznik static void __exit sony_exit(void)
20588025087aSFrank Praznik {
20598025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20608025087aSFrank Praznik 
20618025087aSFrank Praznik 	ida_destroy(&sony_device_id_allocator);
20628025087aSFrank Praznik 	hid_unregister_driver(&sony_driver);
20638025087aSFrank Praznik }
20648025087aSFrank Praznik module_init(sony_init);
20658025087aSFrank Praznik module_exit(sony_exit);
2066bd28ce00SJiri Slaby 
2067bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
2068