xref: /linux/drivers/hid/hid-sony.c (revision ad142b9e44efe4b6faa2553fd1e4d0e3a70619f8)
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 
20*ad142b9eSFrank Praznik /*
21*ad142b9eSFrank 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>
32bd28ce00SJiri Slaby #include <linux/usb.h>
3340e32ee6SJiri Kosina #include <linux/leds.h>
34d902f472SFrank Praznik #include <linux/power_supply.h>
35d902f472SFrank Praznik #include <linux/spinlock.h>
36e5606230SFrank Praznik #include <linux/input/mt.h>
37bd28ce00SJiri Slaby 
38bd28ce00SJiri Slaby #include "hid-ids.h"
39bd28ce00SJiri Slaby 
40f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT       BIT(0)
41f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB    BIT(1)
42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT     BIT(2)
43f1c458caSSven Eckelmann #define BUZZ_CONTROLLER           BIT(3)
44f1c458caSSven Eckelmann #define PS3REMOTE                 BIT(4)
458ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
47cc6e0bbbSJiri Kosina 
48fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
4968330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
5068330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER_BT)
51fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
5268330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER)
53fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
5460781cf4SFrank Praznik 
5560781cf4SFrank Praznik #define MAX_LEDS 4
560a286ef2SSven Eckelmann 
5761ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = {
5861ab44beSSimon Wood 	0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
5961ab44beSSimon Wood 	0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
6061ab44beSSimon Wood 	0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
6161ab44beSSimon Wood };
6261ab44beSSimon Wood 
63e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = {
64e57a67daSMauro Carvalho Chehab 	0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
65e57a67daSMauro Carvalho Chehab 	0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
66e57a67daSMauro Carvalho Chehab 	0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
67e57a67daSMauro Carvalho Chehab 	0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
68e57a67daSMauro Carvalho Chehab 	0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
69e57a67daSMauro Carvalho Chehab 	0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
70e57a67daSMauro Carvalho Chehab 	0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
71e57a67daSMauro Carvalho Chehab 	0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
72e57a67daSMauro Carvalho Chehab 	0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
73e57a67daSMauro Carvalho Chehab 	0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
74e57a67daSMauro Carvalho Chehab 	0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
75e57a67daSMauro Carvalho Chehab 	0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
76e57a67daSMauro Carvalho Chehab 	0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
77e57a67daSMauro Carvalho Chehab 	0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
78e57a67daSMauro Carvalho Chehab 	0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
79e57a67daSMauro Carvalho Chehab 	0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
80e57a67daSMauro Carvalho Chehab 	0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
81e57a67daSMauro Carvalho Chehab 	0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
82e57a67daSMauro Carvalho Chehab 	0xb1, 0x02, 0xc0, 0xc0,
83e57a67daSMauro Carvalho Chehab };
84e57a67daSMauro Carvalho Chehab 
85*ad142b9eSFrank Praznik /*
86*ad142b9eSFrank Praznik  * The default descriptor doesn't provide mapping for the accelerometers
8758d7027bSFrank Praznik  * or orientation sensors.  This fixed descriptor maps the accelerometers
8858d7027bSFrank Praznik  * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
8958d7027bSFrank Praznik  * to usage values 0x43, 0x44 and 0x45.
9058d7027bSFrank Praznik  */
91ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = {
9258d7027bSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
9358d7027bSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
9458d7027bSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
9558d7027bSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
9658d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
9758d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
9858d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
9958d7027bSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
10058d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
10158d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
10258d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
10358d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
10458d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
10558d7027bSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
10658d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
10758d7027bSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
10858d7027bSFrank Praznik 	0x35, 0x00,         /*      Physical Minimum (0),           */
10958d7027bSFrank Praznik 	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
11058d7027bSFrank Praznik 	0x65, 0x14,         /*      Unit (Degrees),                 */
11158d7027bSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
11258d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
11358d7027bSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
11458d7027bSFrank Praznik 	0x65, 0x00,         /*      Unit,                           */
11558d7027bSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
11658d7027bSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
11758d7027bSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
11858d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
11958d7027bSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
12058d7027bSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
12158d7027bSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
12258d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
12358d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
12458d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
12558d7027bSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
12658d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
12758d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
12858d7027bSFrank Praznik 	0x25, 0x7F,         /*      Logical Maximum (127),          */
12958d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
13058d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
13158d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
13258d7027bSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
13358d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
13458d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
13558d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
13658d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
13758d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
13858d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
13958d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
14058d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
14158d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
14258d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
14358d7027bSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
14458d7027bSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
14558d7027bSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
14658d7027bSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
14758d7027bSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
14858d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
14958d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
15058d7027bSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
15158d7027bSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
15258d7027bSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
15358d7027bSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
15458d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
15558d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
15658d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
15758d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
15858d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
15958d7027bSFrank Praznik 	0x25, 0xFF,         /*      Logical Maximum (255),          */
16058d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
16158d7027bSFrank Praznik 	0x95, 0x27,         /*      Report Count (39),              */
16258d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
16358d7027bSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
16458d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
16558d7027bSFrank Praznik 	0x95, 0x1F,         /*      Report Count (31),              */
16658d7027bSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
16758d7027bSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
16858d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
16958d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
17058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
17158d7027bSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
17258d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
17358d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
17458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
17558d7027bSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
17658d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
17758d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
17858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
17958d7027bSFrank Praznik 	0x85, 0x10,         /*      Report ID (16),                 */
18058d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
18158d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
18258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
18358d7027bSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
18458d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
18558d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
18658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
18758d7027bSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
18858d7027bSFrank Praznik 	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
18958d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
19058d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
19158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
19258d7027bSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
19358d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
19458d7027bSFrank Praznik 	0x95, 0x16,         /*      Report Count (22),              */
19558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
19658d7027bSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
19758d7027bSFrank Praznik 	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
19858d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
19958d7027bSFrank Praznik 	0x95, 0x10,         /*      Report Count (16),              */
20058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
20158d7027bSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
20258d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
20358d7027bSFrank Praznik 	0x95, 0x2C,         /*      Report Count (44),              */
20458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
20558d7027bSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
20658d7027bSFrank Praznik 	0x85, 0x80,         /*      Report ID (128),                */
20758d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
20858d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
20958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
21058d7027bSFrank Praznik 	0x85, 0x81,         /*      Report ID (129),                */
21158d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
21258d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
21358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
21458d7027bSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
21558d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
21658d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
21758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
21858d7027bSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
21958d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
22058d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
22158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22258d7027bSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
22358d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
22458d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
22558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22658d7027bSFrank Praznik 	0x85, 0x85,         /*      Report ID (133),                */
22758d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
22858d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
22958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23058d7027bSFrank Praznik 	0x85, 0x86,         /*      Report ID (134),                */
23158d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
23258d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
23358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23458d7027bSFrank Praznik 	0x85, 0x87,         /*      Report ID (135),                */
23558d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
23658d7027bSFrank Praznik 	0x95, 0x23,         /*      Report Count (35),              */
23758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23858d7027bSFrank Praznik 	0x85, 0x88,         /*      Report ID (136),                */
23958d7027bSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
24058d7027bSFrank Praznik 	0x95, 0x22,         /*      Report Count (34),              */
24158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24258d7027bSFrank Praznik 	0x85, 0x89,         /*      Report ID (137),                */
24358d7027bSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
24458d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
24558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24658d7027bSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
24758d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
24858d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
24958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25058d7027bSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
25158d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
25258d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
25358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25458d7027bSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
25558d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
25658d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
25758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25858d7027bSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
25958d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
26058d7027bSFrank Praznik 	0x95, 0x0C,         /*      Report Count (12),              */
26158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26258d7027bSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
26358d7027bSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
26458d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
26558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26658d7027bSFrank Praznik 	0x85, 0xA1,         /*      Report ID (161),                */
26758d7027bSFrank Praznik 	0x09, 0x41,         /*      Usage (41h),                    */
26858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
26958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27058d7027bSFrank Praznik 	0x85, 0xA2,         /*      Report ID (162),                */
27158d7027bSFrank Praznik 	0x09, 0x42,         /*      Usage (42h),                    */
27258d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
27358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27458d7027bSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
27558d7027bSFrank Praznik 	0x09, 0x43,         /*      Usage (43h),                    */
27658d7027bSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
27758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27858d7027bSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
27958d7027bSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
28058d7027bSFrank Praznik 	0x95, 0x0D,         /*      Report Count (13),              */
28158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28258d7027bSFrank Praznik 	0x85, 0xA5,         /*      Report ID (165),                */
28358d7027bSFrank Praznik 	0x09, 0x45,         /*      Usage (45h),                    */
28458d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
28558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28658d7027bSFrank Praznik 	0x85, 0xA6,         /*      Report ID (166),                */
28758d7027bSFrank Praznik 	0x09, 0x46,         /*      Usage (46h),                    */
28858d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
28958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29058d7027bSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
29158d7027bSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
29258d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
29358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29458d7027bSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
29558d7027bSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
29658d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
29758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29858d7027bSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
29958d7027bSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
30058d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
30158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30258d7027bSFrank Praznik 	0x85, 0xA7,         /*      Report ID (167),                */
30358d7027bSFrank Praznik 	0x09, 0x4A,         /*      Usage (4Ah),                    */
30458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
30558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30658d7027bSFrank Praznik 	0x85, 0xA8,         /*      Report ID (168),                */
30758d7027bSFrank Praznik 	0x09, 0x4B,         /*      Usage (4Bh),                    */
30858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
30958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31058d7027bSFrank Praznik 	0x85, 0xA9,         /*      Report ID (169),                */
31158d7027bSFrank Praznik 	0x09, 0x4C,         /*      Usage (4Ch),                    */
31258d7027bSFrank Praznik 	0x95, 0x08,         /*      Report Count (8),               */
31358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31458d7027bSFrank Praznik 	0x85, 0xAA,         /*      Report ID (170),                */
31558d7027bSFrank Praznik 	0x09, 0x4E,         /*      Usage (4Eh),                    */
31658d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
31758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31858d7027bSFrank Praznik 	0x85, 0xAB,         /*      Report ID (171),                */
31958d7027bSFrank Praznik 	0x09, 0x4F,         /*      Usage (4Fh),                    */
32058d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
32158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32258d7027bSFrank Praznik 	0x85, 0xAC,         /*      Report ID (172),                */
32358d7027bSFrank Praznik 	0x09, 0x50,         /*      Usage (50h),                    */
32458d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
32558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32658d7027bSFrank Praznik 	0x85, 0xAD,         /*      Report ID (173),                */
32758d7027bSFrank Praznik 	0x09, 0x51,         /*      Usage (51h),                    */
32858d7027bSFrank Praznik 	0x95, 0x0B,         /*      Report Count (11),              */
32958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33058d7027bSFrank Praznik 	0x85, 0xAE,         /*      Report ID (174),                */
33158d7027bSFrank Praznik 	0x09, 0x52,         /*      Usage (52h),                    */
33258d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
33358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33458d7027bSFrank Praznik 	0x85, 0xAF,         /*      Report ID (175),                */
33558d7027bSFrank Praznik 	0x09, 0x53,         /*      Usage (53h),                    */
33658d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
33758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33858d7027bSFrank Praznik 	0x85, 0xB0,         /*      Report ID (176),                */
33958d7027bSFrank Praznik 	0x09, 0x54,         /*      Usage (54h),                    */
34058d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
34158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34258d7027bSFrank Praznik 	0xC0                /*  End Collection                      */
343ed19d8cfSFrank Praznik };
344ed19d8cfSFrank Praznik 
345*ad142b9eSFrank Praznik /*
346*ad142b9eSFrank Praznik  * The default behavior of the Dualshock 4 is to send reports using report
347d829674dSFrank Praznik  * type 1 when running over Bluetooth. However, as soon as it receives a
348d829674dSFrank Praznik  * report of type 17 to set the LEDs or rumble it starts returning it's state
349d829674dSFrank Praznik  * in report 17 instead of 1.  Since report 17 is undefined in the default HID
350d829674dSFrank Praznik  * descriptor the button and axis definitions must be moved to report 17 or
351d829674dSFrank Praznik  * the HID layer won't process the received input once a report is sent.
352d829674dSFrank Praznik  */
353d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = {
354d829674dSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
355d829674dSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
356d829674dSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
357d829674dSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
358d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
359d829674dSFrank Praznik 	0x95, 0x0A,         /*      Report Count (9),               */
360d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
361d829674dSFrank Praznik 	0x06, 0x04, 0xFF,   /*      Usage Page (FF04h),             */
362d829674dSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
363d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
364d829674dSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
365d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
366d829674dSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
367d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
368d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
369d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
370d829674dSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
371d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
372d829674dSFrank Praznik 	0x95, 0x28,         /*      Report Count (40),              */
373d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
374d829674dSFrank Praznik 	0x85, 0x06,         /*      Report ID (6),                  */
375d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
376d829674dSFrank Praznik 	0x95, 0x34,         /*      Report Count (52),              */
377d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
378d829674dSFrank Praznik 	0x85, 0x07,         /*      Report ID (7),                  */
379d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
380d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
381d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
382d829674dSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
383d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
384d829674dSFrank Praznik 	0x95, 0x2F,         /*      Report Count (47),              */
385d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
386d829674dSFrank Praznik 	0x06, 0x03, 0xFF,   /*      Usage Page (FF03h),             */
387d829674dSFrank Praznik 	0x85, 0x03,         /*      Report ID (3),                  */
388d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
389d829674dSFrank Praznik 	0x95, 0x26,         /*      Report Count (38),              */
390d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
391d829674dSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
392d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
393d829674dSFrank Praznik 	0x95, 0x2E,         /*      Report Count (46),              */
394d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
395d829674dSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
396d829674dSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
397d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
398d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
399d829674dSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
400d829674dSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
401d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
402d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
403d829674dSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
404d829674dSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
405d829674dSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
406d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
407d829674dSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
408d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
409d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
410d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
411d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
412d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
413d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
414d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
415d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
416d829674dSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
417d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
418d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
419d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
420d829674dSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
421d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
422d829674dSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
423d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
424d829674dSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
425d829674dSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
426d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
427d829674dSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
428d829674dSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
429d829674dSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
430d829674dSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
431d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
432d829674dSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
433d829674dSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
434d829674dSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
435d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
436d829674dSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
437d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
438d829674dSFrank Praznik 	0x81, 0x01,         /*      Input (Constant),               */
439d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
440d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
441d829674dSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
442d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
443d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
444d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
445d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
446d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
447d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
448d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
449d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
450d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
451d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
452d829674dSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
453d829674dSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
454d829674dSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
455d829674dSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
456d829674dSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
457d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
458d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
459d829674dSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
460d829674dSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
461d829674dSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
462d829674dSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
463d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
464d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
465d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
466d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
467d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
468d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
469d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
470d829674dSFrank Praznik 	0x95, 0x31,         /*      Report Count (51),              */
471d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
472d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
473d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
474d829674dSFrank Praznik 	0x95, 0x4D,         /*      Report Count (77),              */
475d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
476d829674dSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
477d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
478d829674dSFrank Praznik 	0x95, 0x8D,         /*      Report Count (141),             */
479d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
480d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
481d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
482d829674dSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
483d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
484d829674dSFrank Praznik 	0x95, 0xCD,         /*      Report Count (205),             */
485d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
486d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
487d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
488d829674dSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
489d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
490d829674dSFrank Praznik 	0x96, 0x0D, 0x01,   /*      Report Count (269),             */
491d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
492d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
493d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
494d829674dSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
495d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
496d829674dSFrank Praznik 	0x96, 0x4D, 0x01,   /*      Report Count (333),             */
497d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
498d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
499d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
500d829674dSFrank Praznik 	0x85, 0x16,         /*      Report ID (22),                 */
501d829674dSFrank Praznik 	0x09, 0x2A,         /*      Usage (2Ah),                    */
502d829674dSFrank Praznik 	0x96, 0x8D, 0x01,   /*      Report Count (397),             */
503d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
504d829674dSFrank Praznik 	0x09, 0x2B,         /*      Usage (2Bh),                    */
505d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
506d829674dSFrank Praznik 	0x85, 0x17,         /*      Report ID (23),                 */
507d829674dSFrank Praznik 	0x09, 0x2C,         /*      Usage (2Ch),                    */
508d829674dSFrank Praznik 	0x96, 0xCD, 0x01,   /*      Report Count (461),             */
509d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
510d829674dSFrank Praznik 	0x09, 0x2D,         /*      Usage (2Dh),                    */
511d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
512d829674dSFrank Praznik 	0x85, 0x18,         /*      Report ID (24),                 */
513d829674dSFrank Praznik 	0x09, 0x2E,         /*      Usage (2Eh),                    */
514d829674dSFrank Praznik 	0x96, 0x0D, 0x02,   /*      Report Count (525),             */
515d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
516d829674dSFrank Praznik 	0x09, 0x2F,         /*      Usage (2Fh),                    */
517d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
518d829674dSFrank Praznik 	0x85, 0x19,         /*      Report ID (25),                 */
519d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
520d829674dSFrank Praznik 	0x96, 0x22, 0x02,   /*      Report Count (546),             */
521d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
522d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
523d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
524d829674dSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
525d829674dSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
526d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
527d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
528d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
529d829674dSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
530d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
531d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
532d829674dSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
533d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
534d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
535d829674dSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
536d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
537d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
538d829674dSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
539d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
540d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
541d829674dSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
542d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
543d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
544d829674dSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
545d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
546d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
547d829674dSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
548d829674dSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
549d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
550d829674dSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
551d829674dSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
552d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
553d829674dSFrank Praznik 	0xC0                /*  End Collection                      */
554d829674dSFrank Praznik };
555d829674dSFrank Praznik 
556078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
557078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
558078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
559078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
560078328daSJiri Kosina 
561078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
562078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
563078328daSJiri Kosina 
564078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
565078328daSJiri Kosina 	   * number but it's not needed for correct operation */
566078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
567078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
568078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
569078328daSJiri Kosina 
570078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
571078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
572078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
573078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
574078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
575078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
576078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
577078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
578078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
579078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
580078328daSJiri Kosina 
581078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
582078328daSJiri Kosina 
583078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
584078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
585078328daSJiri Kosina 
586078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
587078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
588078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
589078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
590078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
591078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
592078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
593078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
594078328daSJiri Kosina 	  0x80,              /* MInput  */
595078328daSJiri Kosina 
596078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
597078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
598078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
599078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
600078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
601078328daSJiri Kosina 
602078328daSJiri Kosina 	  /* 12th byte is for battery strength */
603078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
604078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
605078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
606078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
607078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
608078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
609078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
610078328daSJiri Kosina 
611078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
612078328daSJiri Kosina 
613078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
614078328daSJiri Kosina };
615078328daSJiri Kosina 
616078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
617078328daSJiri Kosina 	[0x01] = KEY_SELECT,
618078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
619078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
620078328daSJiri Kosina 	[0x04] = BTN_START,
621078328daSJiri Kosina 	[0x05] = KEY_UP,
622078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
623078328daSJiri Kosina 	[0x07] = KEY_DOWN,
624078328daSJiri Kosina 	[0x08] = KEY_LEFT,
625078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
626078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
627078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
628078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
629078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
630078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
631078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
632078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
633078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
634078328daSJiri Kosina 	[0x14] = KEY_ENTER,
635078328daSJiri Kosina };
636078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
637078328daSJiri Kosina 	[0x00] = KEY_1,
638078328daSJiri Kosina 	[0x01] = KEY_2,
639078328daSJiri Kosina 	[0x02] = KEY_3,
640078328daSJiri Kosina 	[0x03] = KEY_4,
641078328daSJiri Kosina 	[0x04] = KEY_5,
642078328daSJiri Kosina 	[0x05] = KEY_6,
643078328daSJiri Kosina 	[0x06] = KEY_7,
644078328daSJiri Kosina 	[0x07] = KEY_8,
645078328daSJiri Kosina 	[0x08] = KEY_9,
646078328daSJiri Kosina 	[0x09] = KEY_0,
647078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
648078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
649078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
650078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
651078328daSJiri Kosina 	[0x28] = KEY_TIME,
652078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
653078328daSJiri Kosina 	[0x31] = KEY_NEXT,
654078328daSJiri Kosina 	[0x32] = KEY_PLAY,
655078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
656078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
657078328daSJiri Kosina 	[0x38] = KEY_STOP,
658078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
659078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
660078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
661078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
662078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
663078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
664078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
665078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
666078328daSJiri Kosina 	[0x80] = KEY_BLUE,
667078328daSJiri Kosina 	[0x81] = KEY_RED,
668078328daSJiri Kosina 	[0x82] = KEY_GREEN,
669078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
670078328daSJiri Kosina };
671078328daSJiri Kosina 
672f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
673*ad142b9eSFrank Praznik 	/*
674*ad142b9eSFrank Praznik 	 * The controller has 4 remote buzzers, each with one LED and 5
675f04d5140SColin Leitner 	 * buttons.
676f04d5140SColin Leitner 	 *
677f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
678f04d5140SColin Leitner 	 *
679f04d5140SColin Leitner 	 * Key          Offset
680f04d5140SColin Leitner 	 * -------------------
681f04d5140SColin Leitner 	 * Buzz              1
682f04d5140SColin Leitner 	 * Blue              5
683f04d5140SColin Leitner 	 * Orange            4
684f04d5140SColin Leitner 	 * Green             3
685f04d5140SColin Leitner 	 * Yellow            2
686f04d5140SColin Leitner 	 *
687f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
688f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
689f04d5140SColin Leitner 	 */
690f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
691f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
692f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
693f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
694f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
695f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
696f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
697f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
698f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
699f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
700f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
701f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
702f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
703f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
704f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
705f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
706f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
707f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
708f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
709f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
710f04d5140SColin Leitner };
711f04d5140SColin Leitner 
712d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = {
713d902f472SFrank Praznik 	POWER_SUPPLY_PROP_PRESENT,
714d902f472SFrank Praznik 	POWER_SUPPLY_PROP_CAPACITY,
715d902f472SFrank Praznik 	POWER_SUPPLY_PROP_SCOPE,
716d902f472SFrank Praznik 	POWER_SUPPLY_PROP_STATUS,
717d902f472SFrank Praznik };
718d902f472SFrank Praznik 
719cc6e0bbbSJiri Kosina struct sony_sc {
720d902f472SFrank Praznik 	spinlock_t lock;
7210a286ef2SSven Eckelmann 	struct hid_device *hdev;
72260781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
723cc6e0bbbSJiri Kosina 	unsigned long quirks;
7240a286ef2SSven Eckelmann 	struct work_struct state_worker;
725d902f472SFrank Praznik 	struct power_supply battery;
726f04d5140SColin Leitner 
7279f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
7289f323b68SSven Eckelmann 	__u8 left;
7299f323b68SSven Eckelmann 	__u8 right;
7309f323b68SSven Eckelmann #endif
7319f323b68SSven Eckelmann 
732d902f472SFrank Praznik 	__u8 cable_state;
733d902f472SFrank Praznik 	__u8 battery_charging;
734d902f472SFrank Praznik 	__u8 battery_capacity;
73560781cf4SFrank Praznik 	__u8 led_state[MAX_LEDS];
73660781cf4SFrank Praznik 	__u8 led_count;
737cc6e0bbbSJiri Kosina };
738cc6e0bbbSJiri Kosina 
739078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
740078328daSJiri Kosina 			     unsigned int *rsize)
741078328daSJiri Kosina {
742078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
743078328daSJiri Kosina 	return ps3remote_rdesc;
744078328daSJiri Kosina }
745078328daSJiri Kosina 
746078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
747078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
748078328daSJiri Kosina 			     unsigned long **bit, int *max)
749078328daSJiri Kosina {
750078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
751078328daSJiri Kosina 
752078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
753078328daSJiri Kosina 		return -1;
754078328daSJiri Kosina 
755078328daSJiri Kosina 	switch (usage->collection_index) {
756078328daSJiri Kosina 	case 1:
757078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
758078328daSJiri Kosina 			return -1;
759078328daSJiri Kosina 
760078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
761078328daSJiri Kosina 		if (!key)
762078328daSJiri Kosina 			return -1;
763078328daSJiri Kosina 		break;
764078328daSJiri Kosina 	case 2:
765078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
766078328daSJiri Kosina 			return -1;
767078328daSJiri Kosina 
768078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
769078328daSJiri Kosina 		if (!key)
770078328daSJiri Kosina 			return -1;
771078328daSJiri Kosina 		break;
772078328daSJiri Kosina 	default:
773078328daSJiri Kosina 		return -1;
774078328daSJiri Kosina 	}
775078328daSJiri Kosina 
776078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
777078328daSJiri Kosina 	return 1;
778078328daSJiri Kosina }
779078328daSJiri Kosina 
780078328daSJiri Kosina 
781cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
78273e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
78373e4008dSNikolai Kondrashov 		unsigned int *rsize)
784cc6e0bbbSJiri Kosina {
785cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
786cc6e0bbbSJiri Kosina 
78799d24902SFernando Luis Vázquez Cao 	/*
78899d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
78999d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
79099d24902SFernando Luis Vázquez Cao 	 */
79199d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
79299d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
79399d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
79499d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
79599d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
79699d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
79799d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
798a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
79999d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
800cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
801cc6e0bbbSJiri Kosina 	}
80261ab44beSSimon Wood 
803ed19d8cfSFrank Praznik 	/*
804ed19d8cfSFrank Praznik 	 * The default Dualshock 4 USB descriptor doesn't assign
805ed19d8cfSFrank Praznik 	 * the gyroscope values to corresponding axes so we need a
806ed19d8cfSFrank Praznik 	 * modified one.
807ed19d8cfSFrank Praznik 	 */
808ed19d8cfSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
809ed19d8cfSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
810ed19d8cfSFrank Praznik 		rdesc = dualshock4_usb_rdesc;
811ed19d8cfSFrank Praznik 		*rsize = sizeof(dualshock4_usb_rdesc);
812d829674dSFrank Praznik 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
813d829674dSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
814d829674dSFrank Praznik 		rdesc = dualshock4_bt_rdesc;
815d829674dSFrank Praznik 		*rsize = sizeof(dualshock4_bt_rdesc);
816ed19d8cfSFrank Praznik 	}
817ed19d8cfSFrank Praznik 
81861ab44beSSimon Wood 	/* The HID descriptor exposed over BT has a trailing zero byte */
81961ab44beSSimon Wood 	if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
82061ab44beSSimon Wood 			((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
82161ab44beSSimon Wood 			rdesc[83] == 0x75) {
82261ab44beSSimon Wood 		hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
82361ab44beSSimon Wood 		memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
82461ab44beSSimon Wood 			sizeof(sixaxis_rdesc_fixup));
825e57a67daSMauro Carvalho Chehab 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
826e57a67daSMauro Carvalho Chehab 		   *rsize > sizeof(sixaxis_rdesc_fixup2)) {
827e57a67daSMauro Carvalho Chehab 		hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
828e57a67daSMauro Carvalho Chehab 			 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
829e57a67daSMauro Carvalho Chehab 		*rsize = sizeof(sixaxis_rdesc_fixup2);
830e57a67daSMauro Carvalho Chehab 		memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
83161ab44beSSimon Wood 	}
832078328daSJiri Kosina 
833078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
834078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
835078328daSJiri Kosina 
83673e4008dSNikolai Kondrashov 	return rdesc;
837cc6e0bbbSJiri Kosina }
838cc6e0bbbSJiri Kosina 
839d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
840d902f472SFrank Praznik {
841d902f472SFrank Praznik 	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
842d902f472SFrank Praznik 	unsigned long flags;
843d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
844d902f472SFrank Praznik 
845*ad142b9eSFrank Praznik 	/*
846*ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
847d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
848d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
849d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
850d902f472SFrank Praznik 	 */
851d902f472SFrank Praznik 	if (rd[30] >= 0xee) {
852d902f472SFrank Praznik 		battery_capacity = 100;
853a43e94a3SFrank Praznik 		battery_charging = !(rd[30] & 0x01);
854d902f472SFrank Praznik 	} else {
855d902f472SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[rd[30]];
856d902f472SFrank Praznik 		battery_charging = 0;
857d902f472SFrank Praznik 	}
858a43e94a3SFrank Praznik 	cable_state = !((rd[31] >> 4) & 0x01);
859d902f472SFrank Praznik 
860d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
861d902f472SFrank Praznik 	sc->cable_state = cable_state;
862d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
863d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
864d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
865d902f472SFrank Praznik }
866d902f472SFrank Praznik 
867d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
868d902f472SFrank Praznik {
869e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
870e5606230SFrank Praznik 						struct hid_input, list);
871e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
872d902f472SFrank Praznik 	unsigned long flags;
8736c5f860dSFrank Praznik 	int n, offset;
874d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
875d902f472SFrank Praznik 
876*ad142b9eSFrank Praznik 	/*
877*ad142b9eSFrank Praznik 	 * Battery and touchpad data starts at byte 30 in the USB report and
8786c5f860dSFrank Praznik 	 * 32 in Bluetooth report.
8796c5f860dSFrank Praznik 	 */
8806c5f860dSFrank Praznik 	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
8816c5f860dSFrank Praznik 
882*ad142b9eSFrank Praznik 	/*
883*ad142b9eSFrank Praznik 	 * The lower 4 bits of byte 30 contain the battery level
884d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
885d902f472SFrank Praznik 	 */
8866c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
8876c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
888d902f472SFrank Praznik 
889*ad142b9eSFrank Praznik 	/*
890*ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
8916c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
8926c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
893d902f472SFrank Praznik 	 */
8946c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
895d902f472SFrank Praznik 		battery_charging = 0;
896d902f472SFrank Praznik 	else
897d902f472SFrank Praznik 		battery_charging = 1;
898d902f472SFrank Praznik 
8996c5f860dSFrank Praznik 	if (!cable_state)
9006c5f860dSFrank Praznik 		battery_capacity++;
901d902f472SFrank Praznik 	if (battery_capacity > 10)
9026c5f860dSFrank Praznik 		battery_capacity = 10;
9036c5f860dSFrank Praznik 
904d902f472SFrank Praznik 	battery_capacity *= 10;
905d902f472SFrank Praznik 
906d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
907d902f472SFrank Praznik 	sc->cable_state = cable_state;
908d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
909d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
910d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
911e5606230SFrank Praznik 
9126c5f860dSFrank Praznik 	offset += 5;
9136c5f860dSFrank Praznik 
914*ad142b9eSFrank Praznik 	/*
915*ad142b9eSFrank Praznik 	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
9166c5f860dSFrank Praznik 	 * and 37 on Bluetooth.
917e5606230SFrank Praznik 	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
918e5606230SFrank Praznik 	 * indicator that is 0 when pressed and 1 when not pressed.
919e5606230SFrank Praznik 	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
920e5606230SFrank Praznik 	 * The data for the second touch is in the same format and immediatly
921e5606230SFrank Praznik 	 * follows the data for the first.
922e5606230SFrank Praznik 	 */
923e5606230SFrank Praznik 	for (n = 0; n < 2; n++) {
924e5606230SFrank Praznik 		__u16 x, y;
925e5606230SFrank Praznik 
926e5606230SFrank Praznik 		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
927e5606230SFrank Praznik 		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
928e5606230SFrank Praznik 
929e5606230SFrank Praznik 		input_mt_slot(input_dev, n);
930e5606230SFrank Praznik 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
931e5606230SFrank Praznik 					!(rd[offset] >> 7));
932e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
933e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
934e5606230SFrank Praznik 
935e5606230SFrank Praznik 		offset += 4;
936e5606230SFrank Praznik 	}
937d902f472SFrank Praznik }
938d902f472SFrank Praznik 
939c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
940c9e4d877SSimon Wood 		__u8 *rd, int size)
941c9e4d877SSimon Wood {
942c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
943c9e4d877SSimon Wood 
944*ad142b9eSFrank Praznik 	/*
945*ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
946c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
947c9e4d877SSimon Wood 	 */
948fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
949c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
950c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
951c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
952c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
953d902f472SFrank Praznik 
954d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
95568330d83SFrank Praznik 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
95668330d83SFrank Praznik 			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
95768330d83SFrank Praznik 			&& rd[0] == 0x11 && size == 78)) {
958d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
959c9e4d877SSimon Wood 	}
960c9e4d877SSimon Wood 
961c9e4d877SSimon Wood 	return 0;
962c9e4d877SSimon Wood }
963c9e4d877SSimon Wood 
964f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
965f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
966f04d5140SColin Leitner 			unsigned long **bit, int *max)
967f04d5140SColin Leitner {
968f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
969f04d5140SColin Leitner 
970f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
971f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
972f04d5140SColin Leitner 
973f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
974f04d5140SColin Leitner 			return -1;
975f04d5140SColin Leitner 
976f04d5140SColin Leitner 		switch (usage->collection_index) {
977f04d5140SColin Leitner 		case 1:
978f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
979f04d5140SColin Leitner 				return -1;
980f04d5140SColin Leitner 
981f04d5140SColin Leitner 			key = buzz_keymap[key];
982f04d5140SColin Leitner 			if (!key)
983f04d5140SColin Leitner 				return -1;
984f04d5140SColin Leitner 			break;
985f04d5140SColin Leitner 		default:
986f04d5140SColin Leitner 			return -1;
987f04d5140SColin Leitner 		}
988f04d5140SColin Leitner 
989f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
990f04d5140SColin Leitner 		return 1;
991f04d5140SColin Leitner 	}
992f04d5140SColin Leitner 
993078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
994078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
995078328daSJiri Kosina 
9966f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
9976f498018SBenjamin Tissoires 	return 0;
998f04d5140SColin Leitner }
999f04d5140SColin Leitner 
10005710fabfSAntonio Ospite /*
10015710fabfSAntonio Ospite  * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
10025710fabfSAntonio Ospite  * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
10035710fabfSAntonio Ospite  * so we need to override that forcing HID Output Reports on the Control EP.
10045710fabfSAntonio Ospite  *
10055710fabfSAntonio Ospite  * There is also another issue about HID Output Reports via USB, the Sixaxis
10065710fabfSAntonio Ospite  * does not want the report_id as part of the data packet, so we have to
10075710fabfSAntonio Ospite  * discard buf[0] when sending the actual control message, even for numbered
10085710fabfSAntonio Ospite  * reports, humpf!
10095710fabfSAntonio Ospite  */
1010569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
1011569b10a5SAntonio Ospite 		size_t count, unsigned char report_type)
1012569b10a5SAntonio Ospite {
1013569b10a5SAntonio Ospite 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
1014569b10a5SAntonio Ospite 	struct usb_device *dev = interface_to_usbdev(intf);
1015569b10a5SAntonio Ospite 	struct usb_host_interface *interface = intf->cur_altsetting;
1016569b10a5SAntonio Ospite 	int report_id = buf[0];
1017569b10a5SAntonio Ospite 	int ret;
1018569b10a5SAntonio Ospite 
10195710fabfSAntonio Ospite 	if (report_type == HID_OUTPUT_REPORT) {
10205710fabfSAntonio Ospite 		/* Don't send the Report ID */
10215710fabfSAntonio Ospite 		buf++;
10225710fabfSAntonio Ospite 		count--;
10235710fabfSAntonio Ospite 	}
10245710fabfSAntonio Ospite 
1025569b10a5SAntonio Ospite 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1026569b10a5SAntonio Ospite 		HID_REQ_SET_REPORT,
1027569b10a5SAntonio Ospite 		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1028569b10a5SAntonio Ospite 		((report_type + 1) << 8) | report_id,
1029569b10a5SAntonio Ospite 		interface->desc.bInterfaceNumber, buf, count,
1030569b10a5SAntonio Ospite 		USB_CTRL_SET_TIMEOUT);
1031569b10a5SAntonio Ospite 
10325710fabfSAntonio Ospite 	/* Count also the Report ID, in case of an Output report. */
10335710fabfSAntonio Ospite 	if (ret > 0 && report_type == HID_OUTPUT_REPORT)
10345710fabfSAntonio Ospite 		ret++;
10355710fabfSAntonio Ospite 
1036569b10a5SAntonio Ospite 	return ret;
1037569b10a5SAntonio Ospite }
1038569b10a5SAntonio Ospite 
1039bd28ce00SJiri Slaby /*
1040bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1041bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1042bd28ce00SJiri Slaby  * events.
1043bd28ce00SJiri Slaby  */
1044816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1045bd28ce00SJiri Slaby {
1046bd28ce00SJiri Slaby 	int ret;
1047bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
1048bd28ce00SJiri Slaby 
1049bd28ce00SJiri Slaby 	if (!buf)
1050bd28ce00SJiri Slaby 		return -ENOMEM;
1051bd28ce00SJiri Slaby 
1052cafebc05SBenjamin Tissoires 	ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
1053cafebc05SBenjamin Tissoires 				 HID_REQ_GET_REPORT);
1054f204828aSBenjamin Tissoires 
1055bd28ce00SJiri Slaby 	if (ret < 0)
10564291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
1057bd28ce00SJiri Slaby 
1058bd28ce00SJiri Slaby 	kfree(buf);
1059bd28ce00SJiri Slaby 
1060bd28ce00SJiri Slaby 	return ret;
1061bd28ce00SJiri Slaby }
1062bd28ce00SJiri Slaby 
1063816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1064f9ce7c28SBastien Nocera {
1065fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
10667e845d46SBenjamin Tissoires 	return hid_output_raw_report(hdev, buf, sizeof(buf),
10677e845d46SBenjamin Tissoires 				     HID_FEATURE_REPORT);
1068f9ce7c28SBastien Nocera }
1069f9ce7c28SBastien Nocera 
1070*ad142b9eSFrank Praznik /*
1071*ad142b9eSFrank Praznik  * Requesting feature report 0x02 in Bluetooth mode changes the state of the
107268330d83SFrank Praznik  * controller so that it sends full input reports of type 0x11.
107368330d83SFrank Praznik  */
107468330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev)
107568330d83SFrank Praznik {
107668330d83SFrank Praznik 	__u8 buf[37] = { 0 };
107768330d83SFrank Praznik 
107868330d83SFrank Praznik 	return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),
107968330d83SFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
108068330d83SFrank Praznik }
108168330d83SFrank Praznik 
108260781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
1083f04d5140SColin Leitner {
1084f04d5140SColin Leitner 	struct list_head *report_list =
1085f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1086f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1087f04d5140SColin Leitner 		struct hid_report, list);
1088f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
1089f04d5140SColin Leitner 
1090f04d5140SColin Leitner 	value[0] = 0x00;
109160781cf4SFrank Praznik 	value[1] = leds[0] ? 0xff : 0x00;
109260781cf4SFrank Praznik 	value[2] = leds[1] ? 0xff : 0x00;
109360781cf4SFrank Praznik 	value[3] = leds[2] ? 0xff : 0x00;
109460781cf4SFrank Praznik 	value[4] = leds[3] ? 0xff : 0x00;
1095f04d5140SColin Leitner 	value[5] = 0x00;
1096f04d5140SColin Leitner 	value[6] = 0x00;
1097f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1098f04d5140SColin Leitner }
1099f04d5140SColin Leitner 
110060781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count)
11010a286ef2SSven Eckelmann {
11020a286ef2SSven Eckelmann 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
110360781cf4SFrank Praznik 	int n;
11040a286ef2SSven Eckelmann 
110560781cf4SFrank Praznik 	BUG_ON(count > MAX_LEDS);
110660781cf4SFrank Praznik 
110760781cf4SFrank Praznik 	if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {
11080a286ef2SSven Eckelmann 		buzz_set_leds(hdev, leds);
1109fee4e2d5SFrank Praznik 	} else {
111060781cf4SFrank Praznik 		for (n = 0; n < count; n++)
111160781cf4SFrank Praznik 			drv_data->led_state[n] = leds[n];
11120a286ef2SSven Eckelmann 		schedule_work(&drv_data->state_worker);
11130a286ef2SSven Eckelmann 	}
11140a286ef2SSven Eckelmann }
11150a286ef2SSven Eckelmann 
1116c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1117f04d5140SColin Leitner 				    enum led_brightness value)
1118f04d5140SColin Leitner {
1119f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1120f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1121f04d5140SColin Leitner 	struct sony_sc *drv_data;
1122f04d5140SColin Leitner 
1123f04d5140SColin Leitner 	int n;
1124f04d5140SColin Leitner 
1125f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
11262251b85fSSven Eckelmann 	if (!drv_data) {
1127f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1128f04d5140SColin Leitner 		return;
1129f04d5140SColin Leitner 	}
1130f04d5140SColin Leitner 
113160781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
11322251b85fSSven Eckelmann 		if (led == drv_data->leds[n]) {
113360781cf4SFrank Praznik 			if (value != drv_data->led_state[n]) {
113460781cf4SFrank Praznik 				drv_data->led_state[n] = value;
113560781cf4SFrank Praznik 				sony_set_leds(hdev, drv_data->led_state, drv_data->led_count);
1136f04d5140SColin Leitner 			}
1137f04d5140SColin Leitner 			break;
1138f04d5140SColin Leitner 		}
1139f04d5140SColin Leitner 	}
1140f04d5140SColin Leitner }
1141f04d5140SColin Leitner 
1142c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1143f04d5140SColin Leitner {
1144f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1145f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1146f04d5140SColin Leitner 	struct sony_sc *drv_data;
1147f04d5140SColin Leitner 
1148f04d5140SColin Leitner 	int n;
1149f04d5140SColin Leitner 
1150f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
11512251b85fSSven Eckelmann 	if (!drv_data) {
1152f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1153f04d5140SColin Leitner 		return LED_OFF;
1154f04d5140SColin Leitner 	}
1155f04d5140SColin Leitner 
115660781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
11577db7504aSSimon Wood 		if (led == drv_data->leds[n])
11587db7504aSSimon Wood 			return drv_data->led_state[n];
1159f04d5140SColin Leitner 	}
1160f04d5140SColin Leitner 
11617db7504aSSimon Wood 	return LED_OFF;
1162f04d5140SColin Leitner }
1163f04d5140SColin Leitner 
11640a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev)
11650a286ef2SSven Eckelmann {
11660a286ef2SSven Eckelmann 	struct sony_sc *drv_data;
11670a286ef2SSven Eckelmann 	struct led_classdev *led;
11680a286ef2SSven Eckelmann 	int n;
11690a286ef2SSven Eckelmann 
11700a286ef2SSven Eckelmann 	drv_data = hid_get_drvdata(hdev);
11710a286ef2SSven Eckelmann 	BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
11720a286ef2SSven Eckelmann 
117360781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
11740a286ef2SSven Eckelmann 		led = drv_data->leds[n];
11750a286ef2SSven Eckelmann 		drv_data->leds[n] = NULL;
11760a286ef2SSven Eckelmann 		if (!led)
11770a286ef2SSven Eckelmann 			continue;
11780a286ef2SSven Eckelmann 		led_classdev_unregister(led);
11790a286ef2SSven Eckelmann 		kfree(led);
11800a286ef2SSven Eckelmann 	}
118160781cf4SFrank Praznik 
118260781cf4SFrank Praznik 	drv_data->led_count = 0;
11830a286ef2SSven Eckelmann }
11840a286ef2SSven Eckelmann 
1185c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev)
1186f04d5140SColin Leitner {
1187f04d5140SColin Leitner 	struct sony_sc *drv_data;
118840e32ee6SJiri Kosina 	int n, ret = 0;
118960781cf4SFrank Praznik 	int max_brightness;
119061ebca93SFrank Praznik 	int use_colors;
119140e32ee6SJiri Kosina 	struct led_classdev *led;
119240e32ee6SJiri Kosina 	size_t name_sz;
119340e32ee6SJiri Kosina 	char *name;
11940a286ef2SSven Eckelmann 	size_t name_len;
11950a286ef2SSven Eckelmann 	const char *name_fmt;
119661ebca93SFrank Praznik 	static const char * const color_str[] = { "red", "green", "blue" };
119760781cf4SFrank Praznik 	static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
1198f04d5140SColin Leitner 
1199f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12000a286ef2SSven Eckelmann 	BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
1201f04d5140SColin Leitner 
12020a286ef2SSven Eckelmann 	if (drv_data->quirks & BUZZ_CONTROLLER) {
120361ebca93SFrank Praznik 		drv_data->led_count = 4;
120461ebca93SFrank Praznik 		max_brightness = 1;
120561ebca93SFrank Praznik 		use_colors = 0;
12060a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
12070a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
12089446edb9SKees Cook 		/* Validate expected report characteristics. */
12099446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
12109446edb9SKees Cook 			return -ENODEV;
121168330d83SFrank Praznik 	} else if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
121260781cf4SFrank Praznik 		drv_data->led_count = 3;
121360781cf4SFrank Praznik 		max_brightness = 255;
121461ebca93SFrank Praznik 		use_colors = 1;
121561ebca93SFrank Praznik 		name_len = 0;
121661ebca93SFrank Praznik 		name_fmt = "%s:%s";
121760781cf4SFrank Praznik 	} else {
121860781cf4SFrank Praznik 		drv_data->led_count = 4;
121960781cf4SFrank Praznik 		max_brightness = 1;
122061ebca93SFrank Praznik 		use_colors = 0;
122161ebca93SFrank Praznik 		name_len = strlen("::sony#");
122261ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
122360781cf4SFrank Praznik 	}
122460781cf4SFrank Praznik 
1225*ad142b9eSFrank Praznik 	/*
1226*ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1227f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1228*ad142b9eSFrank Praznik 	 * LEDs to on
1229*ad142b9eSFrank Praznik 	 */
123060781cf4SFrank Praznik 	sony_set_leds(hdev, initial_values, drv_data->led_count);
1231f04d5140SColin Leitner 
12320a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1233f04d5140SColin Leitner 
123460781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
123561ebca93SFrank Praznik 
123661ebca93SFrank Praznik 		if (use_colors)
123761ebca93SFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2;
123861ebca93SFrank Praznik 
1239f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1240f04d5140SColin Leitner 		if (!led) {
1241f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
12428cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1243f04d5140SColin Leitner 			goto error_leds;
1244f04d5140SColin Leitner 		}
1245f04d5140SColin Leitner 
1246f04d5140SColin Leitner 		name = (void *)(&led[1]);
124761ebca93SFrank Praznik 		if (use_colors)
124861ebca93SFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_str[n]);
124961ebca93SFrank Praznik 		else
12500a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1251f04d5140SColin Leitner 		led->name = name;
1252f04d5140SColin Leitner 		led->brightness = 0;
125360781cf4SFrank Praznik 		led->max_brightness = max_brightness;
1254c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1255c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1256f04d5140SColin Leitner 
12578cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
12588cd5fcdaSJulia Lawall 		if (ret) {
1259f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
1260f04d5140SColin Leitner 			kfree(led);
1261f04d5140SColin Leitner 			goto error_leds;
1262f04d5140SColin Leitner 		}
1263f04d5140SColin Leitner 
12642251b85fSSven Eckelmann 		drv_data->leds[n] = led;
1265f04d5140SColin Leitner 	}
1266f04d5140SColin Leitner 
1267f04d5140SColin Leitner 	return ret;
1268f04d5140SColin Leitner 
1269f04d5140SColin Leitner error_leds:
12700a286ef2SSven Eckelmann 	sony_leds_remove(hdev);
1271f04d5140SColin Leitner 
1272f04d5140SColin Leitner 	return ret;
1273f04d5140SColin Leitner }
1274f04d5140SColin Leitner 
1275cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
1276a08c22c0SSven Eckelmann {
127792b5c411SSven Eckelmann 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1278a08c22c0SSven Eckelmann 	unsigned char buf[] = {
1279a08c22c0SSven Eckelmann 		0x01,
1280a08c22c0SSven Eckelmann 		0x00, 0xff, 0x00, 0xff, 0x00,
12810a286ef2SSven Eckelmann 		0x00, 0x00, 0x00, 0x00, 0x00,
1282a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
1283a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
1284a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
1285a08c22c0SSven Eckelmann 		0xff, 0x27, 0x10, 0x00, 0x32,
1286a08c22c0SSven Eckelmann 		0x00, 0x00, 0x00, 0x00, 0x00
1287a08c22c0SSven Eckelmann 	};
12889f323b68SSven Eckelmann 
12890a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
12900bd88dd3SFrank Praznik 	buf[3] = sc->right ? 1 : 0;
12919f323b68SSven Eckelmann 	buf[5] = sc->left;
12920a286ef2SSven Eckelmann #endif
12930a286ef2SSven Eckelmann 
129460781cf4SFrank Praznik 	buf[10] |= sc->led_state[0] << 1;
129560781cf4SFrank Praznik 	buf[10] |= sc->led_state[1] << 2;
129660781cf4SFrank Praznik 	buf[10] |= sc->led_state[2] << 3;
129760781cf4SFrank Praznik 	buf[10] |= sc->led_state[3] << 4;
12989f323b68SSven Eckelmann 
1299fee4e2d5SFrank Praznik 	if (sc->quirks & SIXAXIS_CONTROLLER_USB)
13007e845d46SBenjamin Tissoires 		hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT);
1301fee4e2d5SFrank Praznik 	else
1302fee4e2d5SFrank Praznik 		hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf),
1303fee4e2d5SFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
13049f323b68SSven Eckelmann }
13059f323b68SSven Eckelmann 
13060bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
13070bd88dd3SFrank Praznik {
13080bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
13090da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
131048220237SFrank Praznik 	int offset;
13110da8ea65SFrank Praznik 
1312fdcf105dSFrank Praznik 	__u8 buf[78] = { 0 };
131348220237SFrank Praznik 
1314fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
131548220237SFrank Praznik 		buf[0] = 0x05;
131648220237SFrank Praznik 		buf[1] = 0x03;
131748220237SFrank Praznik 		offset = 4;
1318fdcf105dSFrank Praznik 	} else {
1319fdcf105dSFrank Praznik 		buf[0] = 0x11;
1320fdcf105dSFrank Praznik 		buf[1] = 0xB0;
1321fdcf105dSFrank Praznik 		buf[3] = 0x0F;
1322fdcf105dSFrank Praznik 		offset = 6;
1323fdcf105dSFrank Praznik 	}
13240bd88dd3SFrank Praznik 
13250bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
132648220237SFrank Praznik 	buf[offset++] = sc->right;
132748220237SFrank Praznik 	buf[offset++] = sc->left;
132848220237SFrank Praznik #else
132948220237SFrank Praznik 	offset += 2;
13300bd88dd3SFrank Praznik #endif
13310bd88dd3SFrank Praznik 
133248220237SFrank Praznik 	buf[offset++] = sc->led_state[0];
133348220237SFrank Praznik 	buf[offset++] = sc->led_state[1];
133448220237SFrank Praznik 	buf[offset++] = sc->led_state[2];
133560781cf4SFrank Praznik 
1336fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1337fdcf105dSFrank Praznik 		hid_hw_output_report(hdev, buf, 32);
1338fdcf105dSFrank Praznik 	else
1339fdcf105dSFrank Praznik 		hid_hw_raw_request(hdev, 0x11, buf, 78,
1340fdcf105dSFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
13410bd88dd3SFrank Praznik }
13420bd88dd3SFrank Praznik 
13430a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
13449f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
13459f323b68SSven Eckelmann 			    struct ff_effect *effect)
13469f323b68SSven Eckelmann {
1347a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
13489f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
1349a08c22c0SSven Eckelmann 
1350a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
1351a08c22c0SSven Eckelmann 		return 0;
1352a08c22c0SSven Eckelmann 
13539f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
13540bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
1355a08c22c0SSven Eckelmann 
135692b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
13579f323b68SSven Eckelmann 	return 0;
1358a08c22c0SSven Eckelmann }
1359a08c22c0SSven Eckelmann 
1360a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev)
1361a08c22c0SSven Eckelmann {
1362a08c22c0SSven Eckelmann 	struct hid_input *hidinput = list_entry(hdev->inputs.next,
1363a08c22c0SSven Eckelmann 						struct hid_input, list);
1364a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
1365a08c22c0SSven Eckelmann 
1366a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1367a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1368a08c22c0SSven Eckelmann }
1369a08c22c0SSven Eckelmann 
13709f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev)
13719f323b68SSven Eckelmann {
13729f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hdev);
13739f323b68SSven Eckelmann 
137492b5c411SSven Eckelmann 	cancel_work_sync(&sc->state_worker);
13759f323b68SSven Eckelmann }
13769f323b68SSven Eckelmann 
1377a08c22c0SSven Eckelmann #else
1378a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev)
1379a08c22c0SSven Eckelmann {
1380a08c22c0SSven Eckelmann 	return 0;
1381a08c22c0SSven Eckelmann }
13829f323b68SSven Eckelmann 
13839f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev)
13849f323b68SSven Eckelmann {
13859f323b68SSven Eckelmann }
1386a08c22c0SSven Eckelmann #endif
1387a08c22c0SSven Eckelmann 
1388d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
1389d902f472SFrank Praznik 				     enum power_supply_property psp,
1390d902f472SFrank Praznik 				     union power_supply_propval *val)
1391d902f472SFrank Praznik {
1392d902f472SFrank Praznik 	struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
1393d902f472SFrank Praznik 	unsigned long flags;
1394d902f472SFrank Praznik 	int ret = 0;
1395d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
1396d902f472SFrank Praznik 
1397d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1398d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
1399d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
1400d902f472SFrank Praznik 	cable_state = sc->cable_state;
1401d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1402d902f472SFrank Praznik 
1403d902f472SFrank Praznik 	switch (psp) {
1404d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
1405d902f472SFrank Praznik 		val->intval = 1;
1406d902f472SFrank Praznik 		break;
1407d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
1408d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1409d902f472SFrank Praznik 		break;
1410d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
1411d902f472SFrank Praznik 		val->intval = battery_capacity;
1412d902f472SFrank Praznik 		break;
1413d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
1414d902f472SFrank Praznik 		if (battery_charging)
1415d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
1416d902f472SFrank Praznik 		else
1417d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
1418d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
1419d902f472SFrank Praznik 			else
1420d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1421d902f472SFrank Praznik 		break;
1422d902f472SFrank Praznik 	default:
1423d902f472SFrank Praznik 		ret = -EINVAL;
1424d902f472SFrank Praznik 		break;
1425d902f472SFrank Praznik 	}
1426d902f472SFrank Praznik 	return ret;
1427d902f472SFrank Praznik }
1428d902f472SFrank Praznik 
1429d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc)
1430d902f472SFrank Praznik {
1431d902f472SFrank Praznik 	static atomic_t power_id_seq = ATOMIC_INIT(0);
1432d902f472SFrank Praznik 	unsigned long power_id;
1433d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1434d902f472SFrank Praznik 	int ret;
1435d902f472SFrank Praznik 
1436*ad142b9eSFrank Praznik 	/*
1437*ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
1438d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
1439d9a293a9SFrank Praznik 	 */
1440d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
1441d9a293a9SFrank Praznik 
1442d902f472SFrank Praznik 	power_id = (unsigned long)atomic_inc_return(&power_id_seq);
1443d902f472SFrank Praznik 
1444d902f472SFrank Praznik 	sc->battery.properties = sony_battery_props;
1445d902f472SFrank Praznik 	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
1446d902f472SFrank Praznik 	sc->battery.get_property = sony_battery_get_property;
1447d902f472SFrank Praznik 	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1448d902f472SFrank Praznik 	sc->battery.use_for_apm = 0;
1449d902f472SFrank Praznik 	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",
1450d902f472SFrank Praznik 				     power_id);
1451d902f472SFrank Praznik 	if (!sc->battery.name)
1452d902f472SFrank Praznik 		return -ENOMEM;
1453d902f472SFrank Praznik 
1454d902f472SFrank Praznik 	ret = power_supply_register(&hdev->dev, &sc->battery);
1455d902f472SFrank Praznik 	if (ret) {
1456d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
1457d902f472SFrank Praznik 		goto err_free;
1458d902f472SFrank Praznik 	}
1459d902f472SFrank Praznik 
1460d902f472SFrank Praznik 	power_supply_powers(&sc->battery, &hdev->dev);
1461d902f472SFrank Praznik 	return 0;
1462d902f472SFrank Praznik 
1463d902f472SFrank Praznik err_free:
1464d902f472SFrank Praznik 	kfree(sc->battery.name);
1465d902f472SFrank Praznik 	sc->battery.name = NULL;
1466d902f472SFrank Praznik 	return ret;
1467d902f472SFrank Praznik }
1468d902f472SFrank Praznik 
1469d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
1470d902f472SFrank Praznik {
1471d902f472SFrank Praznik 	if (!sc->battery.name)
1472d902f472SFrank Praznik 		return;
1473d902f472SFrank Praznik 
1474d902f472SFrank Praznik 	power_supply_unregister(&sc->battery);
1475d902f472SFrank Praznik 	kfree(sc->battery.name);
1476d902f472SFrank Praznik 	sc->battery.name = NULL;
1477d902f472SFrank Praznik }
1478d902f472SFrank Praznik 
1479e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1480e5606230SFrank Praznik 					int w, int h)
1481e5606230SFrank Praznik {
1482e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1483e5606230SFrank Praznik 						struct hid_input, list);
1484e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
1485e5606230SFrank Praznik 	int ret;
1486e5606230SFrank Praznik 
1487e5606230SFrank Praznik 	ret = input_mt_init_slots(input_dev, touch_count, 0);
1488e5606230SFrank Praznik 	if (ret < 0) {
1489e5606230SFrank Praznik 		hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
1490e5606230SFrank Praznik 		return ret;
1491e5606230SFrank Praznik 	}
1492e5606230SFrank Praznik 
1493e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1494e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1495e5606230SFrank Praznik 
1496e5606230SFrank Praznik 	return 0;
1497e5606230SFrank Praznik }
1498e5606230SFrank Praznik 
1499bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1500bd28ce00SJiri Slaby {
1501bd28ce00SJiri Slaby 	int ret;
1502cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
1503cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
1504f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
1505cc6e0bbbSJiri Kosina 
1506abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
1507cc6e0bbbSJiri Kosina 	if (sc == NULL) {
15084291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
1509cc6e0bbbSJiri Kosina 		return -ENOMEM;
1510cc6e0bbbSJiri Kosina 	}
1511cc6e0bbbSJiri Kosina 
1512cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
1513cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
15140a286ef2SSven Eckelmann 	sc->hdev = hdev;
1515bd28ce00SJiri Slaby 
1516bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
1517bd28ce00SJiri Slaby 	if (ret) {
15184291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
1519abf832bfSBenjamin Tissoires 		return ret;
1520bd28ce00SJiri Slaby 	}
1521bd28ce00SJiri Slaby 
1522f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
1523f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1524f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
1525f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1526f04d5140SColin Leitner 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
1527f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1528f04d5140SColin Leitner 
1529f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
1530bd28ce00SJiri Slaby 	if (ret) {
15314291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
1532abf832bfSBenjamin Tissoires 		return ret;
1533bd28ce00SJiri Slaby 	}
1534bd28ce00SJiri Slaby 
1535569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1536569b10a5SAntonio Ospite 		hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
1537816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
1538cad665a2SFrank Praznik 		INIT_WORK(&sc->state_worker, sixaxis_state_worker);
1539fee4e2d5SFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
1540816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
1541fee4e2d5SFrank Praznik 		INIT_WORK(&sc->state_worker, sixaxis_state_worker);
1542fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
154368330d83SFrank Praznik 		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
154468330d83SFrank Praznik 			ret = dualshock4_set_operational_bt(hdev);
154568330d83SFrank Praznik 			if (ret < 0) {
154668330d83SFrank Praznik 				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
154768330d83SFrank Praznik 				goto err_stop;
154868330d83SFrank Praznik 			}
154968330d83SFrank Praznik 		}
1550*ad142b9eSFrank Praznik 		/*
1551*ad142b9eSFrank Praznik 		 * The Dualshock 4 touchpad supports 2 touches and has a
1552e5606230SFrank Praznik 		 * resolution of 1920x940.
1553e5606230SFrank Praznik 		 */
1554e5606230SFrank Praznik 		ret = sony_register_touchpad(sc, 2, 1920, 940);
1555e5606230SFrank Praznik 		if (ret < 0)
1556e5606230SFrank Praznik 			goto err_stop;
1557e5606230SFrank Praznik 
15580bd88dd3SFrank Praznik 		INIT_WORK(&sc->state_worker, dualshock4_state_worker);
15590bd88dd3SFrank Praznik 	} else {
15600bd88dd3SFrank Praznik 		ret = 0;
15610bd88dd3SFrank Praznik 	}
1562f9ce7c28SBastien Nocera 
15634dfdc464SJiri Kosina 	if (ret < 0)
1564bd28ce00SJiri Slaby 		goto err_stop;
1565bd28ce00SJiri Slaby 
15660a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
15670a286ef2SSven Eckelmann 		ret = sony_leds_init(hdev);
15680a286ef2SSven Eckelmann 		if (ret < 0)
15690a286ef2SSven Eckelmann 			goto err_stop;
15700a286ef2SSven Eckelmann 	}
15710a286ef2SSven Eckelmann 
1572d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1573d902f472SFrank Praznik 		ret = sony_battery_probe(sc);
1574a08c22c0SSven Eckelmann 		if (ret < 0)
1575a08c22c0SSven Eckelmann 			goto err_stop;
1576a08c22c0SSven Eckelmann 
1577d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
1578d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
1579d902f472SFrank Praznik 		if (ret < 0) {
1580d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
1581d902f472SFrank Praznik 			goto err_stop;
1582d902f472SFrank Praznik 		}
1583d902f472SFrank Praznik 	}
1584d902f472SFrank Praznik 
1585d902f472SFrank Praznik 	ret = sony_init_ff(hdev);
1586d902f472SFrank Praznik 	if (ret < 0)
1587d902f472SFrank Praznik 		goto err_close;
1588d902f472SFrank Praznik 
1589bd28ce00SJiri Slaby 	return 0;
1590d902f472SFrank Praznik err_close:
1591d902f472SFrank Praznik 	hid_hw_close(hdev);
1592bd28ce00SJiri Slaby err_stop:
15930a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
15940a286ef2SSven Eckelmann 		sony_leds_remove(hdev);
1595d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
1596d902f472SFrank Praznik 		sony_battery_remove(sc);
1597bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
1598bd28ce00SJiri Slaby 	return ret;
1599bd28ce00SJiri Slaby }
1600bd28ce00SJiri Slaby 
1601cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev)
1602cc6e0bbbSJiri Kosina {
1603f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1604f04d5140SColin Leitner 
16050a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1606c5382519SSven Eckelmann 		sony_leds_remove(hdev);
1607f04d5140SColin Leitner 
1608d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1609d902f472SFrank Praznik 		hid_hw_close(hdev);
1610d902f472SFrank Praznik 		sony_battery_remove(sc);
1611d902f472SFrank Praznik 	}
1612d902f472SFrank Praznik 
16139f323b68SSven Eckelmann 	sony_destroy_ff(hdev);
16149f323b68SSven Eckelmann 
1615cc6e0bbbSJiri Kosina 	hid_hw_stop(hdev);
1616cc6e0bbbSJiri Kosina }
1617cc6e0bbbSJiri Kosina 
1618bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
1619816651a7SAntonio Ospite 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1620816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_USB },
162135dca5b4SJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
162235dca5b4SJiri Kosina 		.driver_data = SIXAXIS_CONTROLLER_USB },
1623816651a7SAntonio Ospite 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1624816651a7SAntonio Ospite 		.driver_data = SIXAXIS_CONTROLLER_BT },
1625cc6e0bbbSJiri Kosina 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
1626cc6e0bbbSJiri Kosina 		.driver_data = VAIO_RDESC_CONSTANT },
1627a4649184SFernando Luis Vázquez Cao 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
1628a4649184SFernando Luis Vázquez Cao 		.driver_data = VAIO_RDESC_CONSTANT },
1629f04d5140SColin Leitner 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
1630f04d5140SColin Leitner 	 * Logitech joystick from the device descriptor. */
1631f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
1632f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
1633f04d5140SColin Leitner 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
1634f04d5140SColin Leitner 		.driver_data = BUZZ_CONTROLLER },
1635078328daSJiri Kosina 	/* PS3 BD Remote Control */
1636078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
1637078328daSJiri Kosina 		.driver_data = PS3REMOTE },
1638078328daSJiri Kosina 	/* Logitech Harmony Adapter for PS3 */
1639078328daSJiri Kosina 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
1640078328daSJiri Kosina 		.driver_data = PS3REMOTE },
16410bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
16420bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
16438ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
16440bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
16458ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
1646bd28ce00SJiri Slaby 	{ }
1647bd28ce00SJiri Slaby };
1648bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
1649bd28ce00SJiri Slaby 
1650bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
1651bd28ce00SJiri Slaby 	.name          = "sony",
1652bd28ce00SJiri Slaby 	.id_table      = sony_devices,
1653f04d5140SColin Leitner 	.input_mapping = sony_mapping,
1654bd28ce00SJiri Slaby 	.probe         = sony_probe,
1655cc6e0bbbSJiri Kosina 	.remove        = sony_remove,
1656cc6e0bbbSJiri Kosina 	.report_fixup  = sony_report_fixup,
1657c9e4d877SSimon Wood 	.raw_event     = sony_raw_event
1658bd28ce00SJiri Slaby };
1659f425458eSH Hartley Sweeten module_hid_driver(sony_driver);
1660bd28ce00SJiri Slaby 
1661bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
1662