xref: /linux/drivers/hid/hid-sony.c (revision 50764650c9e6e8498d273ad714f68ee8eec96692)
1bd28ce00SJiri Slaby /*
2078328daSJiri Kosina  *  HID driver for Sony / PS2 / PS3 BD devices.
3bd28ce00SJiri Slaby  *
4bd28ce00SJiri Slaby  *  Copyright (c) 1999 Andreas Gal
5bd28ce00SJiri Slaby  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6bd28ce00SJiri Slaby  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7bd28ce00SJiri Slaby  *  Copyright (c) 2008 Jiri Slaby
8078328daSJiri Kosina  *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
9078328daSJiri Kosina  *  Copyright (c) 2006-2013 Jiri Kosina
10f04d5140SColin Leitner  *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
11bd28ce00SJiri Slaby  */
12bd28ce00SJiri Slaby 
13bd28ce00SJiri Slaby /*
14bd28ce00SJiri Slaby  * This program is free software; you can redistribute it and/or modify it
15bd28ce00SJiri Slaby  * under the terms of the GNU General Public License as published by the Free
16bd28ce00SJiri Slaby  * Software Foundation; either version 2 of the License, or (at your option)
17bd28ce00SJiri Slaby  * any later version.
18bd28ce00SJiri Slaby  */
19bd28ce00SJiri Slaby 
20ad142b9eSFrank Praznik /*
21ad142b9eSFrank Praznik  * NOTE: in order for the Sony PS3 BD Remote Control to be found by
22078328daSJiri Kosina  * a Bluetooth host, the key combination Start+Enter has to be kept pressed
23078328daSJiri Kosina  * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
24078328daSJiri Kosina  *
25078328daSJiri Kosina  * There will be no PIN request from the device.
26078328daSJiri Kosina  */
27078328daSJiri Kosina 
28bd28ce00SJiri Slaby #include <linux/device.h>
29bd28ce00SJiri Slaby #include <linux/hid.h>
30bd28ce00SJiri Slaby #include <linux/module.h>
315a0e3ad6STejun Heo #include <linux/slab.h>
3240e32ee6SJiri Kosina #include <linux/leds.h>
33d902f472SFrank Praznik #include <linux/power_supply.h>
34d902f472SFrank Praznik #include <linux/spinlock.h>
35d2d782fcSFrank Praznik #include <linux/list.h>
368025087aSFrank Praznik #include <linux/idr.h>
37e5606230SFrank Praznik #include <linux/input/mt.h>
38bd28ce00SJiri Slaby 
39bd28ce00SJiri Slaby #include "hid-ids.h"
40bd28ce00SJiri Slaby 
41f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT       BIT(0)
42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB    BIT(1)
43f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT     BIT(2)
44f1c458caSSven Eckelmann #define BUZZ_CONTROLLER           BIT(3)
45f1c458caSSven Eckelmann #define PS3REMOTE                 BIT(4)
468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
478ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
48cc6e0bbbSJiri Kosina 
49fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
5068330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
5168330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER_BT)
52fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
5368330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER)
54fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
55c8de9dbbSFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
5660781cf4SFrank Praznik 
5760781cf4SFrank Praznik #define MAX_LEDS 4
580a286ef2SSven Eckelmann 
5961ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = {
6061ab44beSSimon Wood 	0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
6161ab44beSSimon Wood 	0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
6261ab44beSSimon Wood 	0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
6361ab44beSSimon Wood };
6461ab44beSSimon Wood 
65e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = {
66e57a67daSMauro Carvalho Chehab 	0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
67e57a67daSMauro Carvalho Chehab 	0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
68e57a67daSMauro Carvalho Chehab 	0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
69e57a67daSMauro Carvalho Chehab 	0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
70e57a67daSMauro Carvalho Chehab 	0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
71e57a67daSMauro Carvalho Chehab 	0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
72e57a67daSMauro Carvalho Chehab 	0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
73e57a67daSMauro Carvalho Chehab 	0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
74e57a67daSMauro Carvalho Chehab 	0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
75e57a67daSMauro Carvalho Chehab 	0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
76e57a67daSMauro Carvalho Chehab 	0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
77e57a67daSMauro Carvalho Chehab 	0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
78e57a67daSMauro Carvalho Chehab 	0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
79e57a67daSMauro Carvalho Chehab 	0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
80e57a67daSMauro Carvalho Chehab 	0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
81e57a67daSMauro Carvalho Chehab 	0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
82e57a67daSMauro Carvalho Chehab 	0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
83e57a67daSMauro Carvalho Chehab 	0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
84e57a67daSMauro Carvalho Chehab 	0xb1, 0x02, 0xc0, 0xc0,
85e57a67daSMauro Carvalho Chehab };
86e57a67daSMauro Carvalho Chehab 
87ad142b9eSFrank Praznik /*
88ad142b9eSFrank Praznik  * The default descriptor doesn't provide mapping for the accelerometers
8958d7027bSFrank Praznik  * or orientation sensors.  This fixed descriptor maps the accelerometers
9058d7027bSFrank Praznik  * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
9158d7027bSFrank Praznik  * to usage values 0x43, 0x44 and 0x45.
9258d7027bSFrank Praznik  */
93ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = {
9458d7027bSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
9558d7027bSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
9658d7027bSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
9758d7027bSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
9858d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
9958d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
10058d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
10158d7027bSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
10258d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
10358d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
10458d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
10558d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
10658d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
10758d7027bSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
10858d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
10958d7027bSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
11058d7027bSFrank Praznik 	0x35, 0x00,         /*      Physical Minimum (0),           */
11158d7027bSFrank Praznik 	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
11258d7027bSFrank Praznik 	0x65, 0x14,         /*      Unit (Degrees),                 */
11358d7027bSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
11458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
11558d7027bSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
11658d7027bSFrank Praznik 	0x65, 0x00,         /*      Unit,                           */
11758d7027bSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
11858d7027bSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
11958d7027bSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
12058d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
12158d7027bSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
12258d7027bSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
12358d7027bSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
12458d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
12558d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
12658d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
12758d7027bSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
12858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
12958d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
13058d7027bSFrank Praznik 	0x25, 0x7F,         /*      Logical Maximum (127),          */
13158d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
13258d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
13358d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
13458d7027bSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
13558d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
13658d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
13758d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
13858d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
13958d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
14058d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
14158d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
14258d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
14358d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
14458d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
14558d7027bSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
14658d7027bSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
14758d7027bSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
14858d7027bSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
14958d7027bSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
15058d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
15158d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
15258d7027bSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
15358d7027bSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
15458d7027bSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
15558d7027bSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
15658d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
15758d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
15858d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
15958d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
16058d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
16158d7027bSFrank Praznik 	0x25, 0xFF,         /*      Logical Maximum (255),          */
16258d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
16358d7027bSFrank Praznik 	0x95, 0x27,         /*      Report Count (39),              */
16458d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
16558d7027bSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
16658d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
16758d7027bSFrank Praznik 	0x95, 0x1F,         /*      Report Count (31),              */
16858d7027bSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
16958d7027bSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
17058d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
17158d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
17258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
17358d7027bSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
17458d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
17558d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
17658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
17758d7027bSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
17858d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
17958d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
18058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
18158d7027bSFrank Praznik 	0x85, 0x10,         /*      Report ID (16),                 */
18258d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
18358d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
18458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
18558d7027bSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
18658d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
18758d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
18858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
18958d7027bSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
19058d7027bSFrank Praznik 	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
19158d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
19258d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
19358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
19458d7027bSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
19558d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
19658d7027bSFrank Praznik 	0x95, 0x16,         /*      Report Count (22),              */
19758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
19858d7027bSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
19958d7027bSFrank Praznik 	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
20058d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
20158d7027bSFrank Praznik 	0x95, 0x10,         /*      Report Count (16),              */
20258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
20358d7027bSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
20458d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
20558d7027bSFrank Praznik 	0x95, 0x2C,         /*      Report Count (44),              */
20658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
20758d7027bSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
20858d7027bSFrank Praznik 	0x85, 0x80,         /*      Report ID (128),                */
20958d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
21058d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
21158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
21258d7027bSFrank Praznik 	0x85, 0x81,         /*      Report ID (129),                */
21358d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
21458d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
21558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
21658d7027bSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
21758d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
21858d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
21958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22058d7027bSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
22158d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
22258d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
22358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22458d7027bSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
22558d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
22658d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
22758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
22858d7027bSFrank Praznik 	0x85, 0x85,         /*      Report ID (133),                */
22958d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
23058d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
23158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23258d7027bSFrank Praznik 	0x85, 0x86,         /*      Report ID (134),                */
23358d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
23458d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
23558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
23658d7027bSFrank Praznik 	0x85, 0x87,         /*      Report ID (135),                */
23758d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
23858d7027bSFrank Praznik 	0x95, 0x23,         /*      Report Count (35),              */
23958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24058d7027bSFrank Praznik 	0x85, 0x88,         /*      Report ID (136),                */
24158d7027bSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
24258d7027bSFrank Praznik 	0x95, 0x22,         /*      Report Count (34),              */
24358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24458d7027bSFrank Praznik 	0x85, 0x89,         /*      Report ID (137),                */
24558d7027bSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
24658d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
24758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
24858d7027bSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
24958d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
25058d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
25158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25258d7027bSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
25358d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
25458d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
25558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
25658d7027bSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
25758d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
25858d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
25958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26058d7027bSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
26158d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
26258d7027bSFrank Praznik 	0x95, 0x0C,         /*      Report Count (12),              */
26358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26458d7027bSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
26558d7027bSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
26658d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
26758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
26858d7027bSFrank Praznik 	0x85, 0xA1,         /*      Report ID (161),                */
26958d7027bSFrank Praznik 	0x09, 0x41,         /*      Usage (41h),                    */
27058d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
27158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27258d7027bSFrank Praznik 	0x85, 0xA2,         /*      Report ID (162),                */
27358d7027bSFrank Praznik 	0x09, 0x42,         /*      Usage (42h),                    */
27458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
27558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
27658d7027bSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
27758d7027bSFrank Praznik 	0x09, 0x43,         /*      Usage (43h),                    */
27858d7027bSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
27958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28058d7027bSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
28158d7027bSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
28258d7027bSFrank Praznik 	0x95, 0x0D,         /*      Report Count (13),              */
28358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28458d7027bSFrank Praznik 	0x85, 0xA5,         /*      Report ID (165),                */
28558d7027bSFrank Praznik 	0x09, 0x45,         /*      Usage (45h),                    */
28658d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
28758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
28858d7027bSFrank Praznik 	0x85, 0xA6,         /*      Report ID (166),                */
28958d7027bSFrank Praznik 	0x09, 0x46,         /*      Usage (46h),                    */
29058d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
29158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29258d7027bSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
29358d7027bSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
29458d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
29558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
29658d7027bSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
29758d7027bSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
29858d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
29958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30058d7027bSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
30158d7027bSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
30258d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
30358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30458d7027bSFrank Praznik 	0x85, 0xA7,         /*      Report ID (167),                */
30558d7027bSFrank Praznik 	0x09, 0x4A,         /*      Usage (4Ah),                    */
30658d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
30758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
30858d7027bSFrank Praznik 	0x85, 0xA8,         /*      Report ID (168),                */
30958d7027bSFrank Praznik 	0x09, 0x4B,         /*      Usage (4Bh),                    */
31058d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
31158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31258d7027bSFrank Praznik 	0x85, 0xA9,         /*      Report ID (169),                */
31358d7027bSFrank Praznik 	0x09, 0x4C,         /*      Usage (4Ch),                    */
31458d7027bSFrank Praznik 	0x95, 0x08,         /*      Report Count (8),               */
31558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
31658d7027bSFrank Praznik 	0x85, 0xAA,         /*      Report ID (170),                */
31758d7027bSFrank Praznik 	0x09, 0x4E,         /*      Usage (4Eh),                    */
31858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
31958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32058d7027bSFrank Praznik 	0x85, 0xAB,         /*      Report ID (171),                */
32158d7027bSFrank Praznik 	0x09, 0x4F,         /*      Usage (4Fh),                    */
32258d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
32358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32458d7027bSFrank Praznik 	0x85, 0xAC,         /*      Report ID (172),                */
32558d7027bSFrank Praznik 	0x09, 0x50,         /*      Usage (50h),                    */
32658d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
32758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
32858d7027bSFrank Praznik 	0x85, 0xAD,         /*      Report ID (173),                */
32958d7027bSFrank Praznik 	0x09, 0x51,         /*      Usage (51h),                    */
33058d7027bSFrank Praznik 	0x95, 0x0B,         /*      Report Count (11),              */
33158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33258d7027bSFrank Praznik 	0x85, 0xAE,         /*      Report ID (174),                */
33358d7027bSFrank Praznik 	0x09, 0x52,         /*      Usage (52h),                    */
33458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
33558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33658d7027bSFrank Praznik 	0x85, 0xAF,         /*      Report ID (175),                */
33758d7027bSFrank Praznik 	0x09, 0x53,         /*      Usage (53h),                    */
33858d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
33958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34058d7027bSFrank Praznik 	0x85, 0xB0,         /*      Report ID (176),                */
34158d7027bSFrank Praznik 	0x09, 0x54,         /*      Usage (54h),                    */
34258d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
34358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34458d7027bSFrank Praznik 	0xC0                /*  End Collection                      */
345ed19d8cfSFrank Praznik };
346ed19d8cfSFrank Praznik 
347ad142b9eSFrank Praznik /*
348ad142b9eSFrank Praznik  * The default behavior of the Dualshock 4 is to send reports using report
349d829674dSFrank Praznik  * type 1 when running over Bluetooth. However, as soon as it receives a
350d829674dSFrank Praznik  * report of type 17 to set the LEDs or rumble it starts returning it's state
351d829674dSFrank Praznik  * in report 17 instead of 1.  Since report 17 is undefined in the default HID
352d829674dSFrank Praznik  * descriptor the button and axis definitions must be moved to report 17 or
353d829674dSFrank Praznik  * the HID layer won't process the received input once a report is sent.
354d829674dSFrank Praznik  */
355d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = {
356d829674dSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
357d829674dSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
358d829674dSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
359d829674dSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
360d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
361d829674dSFrank Praznik 	0x95, 0x0A,         /*      Report Count (9),               */
362d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
363d829674dSFrank Praznik 	0x06, 0x04, 0xFF,   /*      Usage Page (FF04h),             */
364d829674dSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
365d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
366d829674dSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
367d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
368d829674dSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
369d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
370d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
371d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
372d829674dSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
373d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
374d829674dSFrank Praznik 	0x95, 0x28,         /*      Report Count (40),              */
375d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
376d829674dSFrank Praznik 	0x85, 0x06,         /*      Report ID (6),                  */
377d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
378d829674dSFrank Praznik 	0x95, 0x34,         /*      Report Count (52),              */
379d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
380d829674dSFrank Praznik 	0x85, 0x07,         /*      Report ID (7),                  */
381d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
382d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
383d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
384d829674dSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
385d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
386d829674dSFrank Praznik 	0x95, 0x2F,         /*      Report Count (47),              */
387d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
388d829674dSFrank Praznik 	0x06, 0x03, 0xFF,   /*      Usage Page (FF03h),             */
389d829674dSFrank Praznik 	0x85, 0x03,         /*      Report ID (3),                  */
390d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
391d829674dSFrank Praznik 	0x95, 0x26,         /*      Report Count (38),              */
392d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
393d829674dSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
394d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
395d829674dSFrank Praznik 	0x95, 0x2E,         /*      Report Count (46),              */
396d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
397d829674dSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
398d829674dSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
399d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
400d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
401d829674dSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
402d829674dSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
403d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
404d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
405d829674dSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
406d829674dSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
407d829674dSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
408d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
409d829674dSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
410d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
411d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
412d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
413d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
414d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
415d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
416d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
417d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
418d829674dSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
419d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
420d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
421d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
422d829674dSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
423d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
424d829674dSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
425d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
426d829674dSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
427d829674dSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
428d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
429d829674dSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
430d829674dSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
431d829674dSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
432d829674dSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
433d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
434d829674dSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
435d829674dSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
436d829674dSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
437d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
438d829674dSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
439d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
440d829674dSFrank Praznik 	0x81, 0x01,         /*      Input (Constant),               */
441d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
442d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
443d829674dSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
444d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
445d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
446d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
447d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
448d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
449d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
450d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
451d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
452d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
453d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
454d829674dSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
455d829674dSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
456d829674dSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
457d829674dSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
458d829674dSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
459d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
460d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
461d829674dSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
462d829674dSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
463d829674dSFrank Praznik 	0x16, 0xFF, 0xBF,   /*      Logical Minimum (-16385),       */
464d829674dSFrank Praznik 	0x26, 0x00, 0x40,   /*      Logical Maximum (16384),        */
465d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
466d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
467d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
468d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
469d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
470d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
471d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
472d829674dSFrank Praznik 	0x95, 0x31,         /*      Report Count (51),              */
473d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
474d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
475d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
476d829674dSFrank Praznik 	0x95, 0x4D,         /*      Report Count (77),              */
477d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
478d829674dSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
479d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
480d829674dSFrank Praznik 	0x95, 0x8D,         /*      Report Count (141),             */
481d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
482d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
483d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
484d829674dSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
485d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
486d829674dSFrank Praznik 	0x95, 0xCD,         /*      Report Count (205),             */
487d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
488d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
489d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
490d829674dSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
491d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
492d829674dSFrank Praznik 	0x96, 0x0D, 0x01,   /*      Report Count (269),             */
493d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
494d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
495d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
496d829674dSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
497d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
498d829674dSFrank Praznik 	0x96, 0x4D, 0x01,   /*      Report Count (333),             */
499d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
500d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
501d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
502d829674dSFrank Praznik 	0x85, 0x16,         /*      Report ID (22),                 */
503d829674dSFrank Praznik 	0x09, 0x2A,         /*      Usage (2Ah),                    */
504d829674dSFrank Praznik 	0x96, 0x8D, 0x01,   /*      Report Count (397),             */
505d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
506d829674dSFrank Praznik 	0x09, 0x2B,         /*      Usage (2Bh),                    */
507d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
508d829674dSFrank Praznik 	0x85, 0x17,         /*      Report ID (23),                 */
509d829674dSFrank Praznik 	0x09, 0x2C,         /*      Usage (2Ch),                    */
510d829674dSFrank Praznik 	0x96, 0xCD, 0x01,   /*      Report Count (461),             */
511d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
512d829674dSFrank Praznik 	0x09, 0x2D,         /*      Usage (2Dh),                    */
513d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
514d829674dSFrank Praznik 	0x85, 0x18,         /*      Report ID (24),                 */
515d829674dSFrank Praznik 	0x09, 0x2E,         /*      Usage (2Eh),                    */
516d829674dSFrank Praznik 	0x96, 0x0D, 0x02,   /*      Report Count (525),             */
517d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
518d829674dSFrank Praznik 	0x09, 0x2F,         /*      Usage (2Fh),                    */
519d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
520d829674dSFrank Praznik 	0x85, 0x19,         /*      Report ID (25),                 */
521d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
522d829674dSFrank Praznik 	0x96, 0x22, 0x02,   /*      Report Count (546),             */
523d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
524d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
525d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
526d829674dSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
527d829674dSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
528d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
529d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
530d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
531d829674dSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
532d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
533d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
534d829674dSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
535d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
536d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
537d829674dSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
538d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
539d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
540d829674dSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
541d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
542d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
543d829674dSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
544d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
545d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
546d829674dSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
547d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
548d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
549d829674dSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
550d829674dSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
551d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
552d829674dSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
553d829674dSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
554d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
555d829674dSFrank Praznik 	0xC0                /*  End Collection                      */
556d829674dSFrank Praznik };
557d829674dSFrank Praznik 
558078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
559078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
560078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
561078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
562078328daSJiri Kosina 
563078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
564078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
565078328daSJiri Kosina 
566078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
567078328daSJiri Kosina 	   * number but it's not needed for correct operation */
568078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
569078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
570078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
571078328daSJiri Kosina 
572078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
573078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
574078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
575078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
576078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
577078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
578078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
579078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
580078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
581078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
582078328daSJiri Kosina 
583078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
584078328daSJiri Kosina 
585078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
586078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
587078328daSJiri Kosina 
588078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
589078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
590078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
591078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
592078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
593078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
594078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
595078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
596078328daSJiri Kosina 	  0x80,              /* MInput  */
597078328daSJiri Kosina 
598078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
599078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
600078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
601078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
602078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
603078328daSJiri Kosina 
604078328daSJiri Kosina 	  /* 12th byte is for battery strength */
605078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
606078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
607078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
608078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
609078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
610078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
611078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
612078328daSJiri Kosina 
613078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
614078328daSJiri Kosina 
615078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
616078328daSJiri Kosina };
617078328daSJiri Kosina 
618078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
619078328daSJiri Kosina 	[0x01] = KEY_SELECT,
620078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
621078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
622078328daSJiri Kosina 	[0x04] = BTN_START,
623078328daSJiri Kosina 	[0x05] = KEY_UP,
624078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
625078328daSJiri Kosina 	[0x07] = KEY_DOWN,
626078328daSJiri Kosina 	[0x08] = KEY_LEFT,
627078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
628078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
629078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
630078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
631078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
632078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
633078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
634078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
635078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
636078328daSJiri Kosina 	[0x14] = KEY_ENTER,
637078328daSJiri Kosina };
638078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
639078328daSJiri Kosina 	[0x00] = KEY_1,
640078328daSJiri Kosina 	[0x01] = KEY_2,
641078328daSJiri Kosina 	[0x02] = KEY_3,
642078328daSJiri Kosina 	[0x03] = KEY_4,
643078328daSJiri Kosina 	[0x04] = KEY_5,
644078328daSJiri Kosina 	[0x05] = KEY_6,
645078328daSJiri Kosina 	[0x06] = KEY_7,
646078328daSJiri Kosina 	[0x07] = KEY_8,
647078328daSJiri Kosina 	[0x08] = KEY_9,
648078328daSJiri Kosina 	[0x09] = KEY_0,
649078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
650078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
651078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
652078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
653078328daSJiri Kosina 	[0x28] = KEY_TIME,
654078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
655078328daSJiri Kosina 	[0x31] = KEY_NEXT,
656078328daSJiri Kosina 	[0x32] = KEY_PLAY,
657078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
658078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
659078328daSJiri Kosina 	[0x38] = KEY_STOP,
660078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
661078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
662078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
663078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
664078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
665078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
666078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
667078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
668078328daSJiri Kosina 	[0x80] = KEY_BLUE,
669078328daSJiri Kosina 	[0x81] = KEY_RED,
670078328daSJiri Kosina 	[0x82] = KEY_GREEN,
671078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
672078328daSJiri Kosina };
673078328daSJiri Kosina 
674f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
675ad142b9eSFrank Praznik 	/*
676ad142b9eSFrank Praznik 	 * The controller has 4 remote buzzers, each with one LED and 5
677f04d5140SColin Leitner 	 * buttons.
678f04d5140SColin Leitner 	 *
679f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
680f04d5140SColin Leitner 	 *
681f04d5140SColin Leitner 	 * Key          Offset
682f04d5140SColin Leitner 	 * -------------------
683f04d5140SColin Leitner 	 * Buzz              1
684f04d5140SColin Leitner 	 * Blue              5
685f04d5140SColin Leitner 	 * Orange            4
686f04d5140SColin Leitner 	 * Green             3
687f04d5140SColin Leitner 	 * Yellow            2
688f04d5140SColin Leitner 	 *
689f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
690f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
691f04d5140SColin Leitner 	 */
692f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
693f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
694f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
695f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
696f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
697f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
698f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
699f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
700f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
701f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
702f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
703f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
704f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
705f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
706f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
707f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
708f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
709f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
710f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
711f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
712f04d5140SColin Leitner };
713f04d5140SColin Leitner 
714d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = {
715d902f472SFrank Praznik 	POWER_SUPPLY_PROP_PRESENT,
716d902f472SFrank Praznik 	POWER_SUPPLY_PROP_CAPACITY,
717d902f472SFrank Praznik 	POWER_SUPPLY_PROP_SCOPE,
718d902f472SFrank Praznik 	POWER_SUPPLY_PROP_STATUS,
719d902f472SFrank Praznik };
720d902f472SFrank Praznik 
72155d3b664SFrank Praznik struct sixaxis_led {
72255d3b664SFrank Praznik 	__u8 time_enabled; /* the total time the led is active (0xff means forever) */
72355d3b664SFrank Praznik 	__u8 duty_length;  /* how long a cycle is in deciseconds (0 means "really fast") */
72455d3b664SFrank Praznik 	__u8 enabled;
72555d3b664SFrank Praznik 	__u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
72655d3b664SFrank Praznik 	__u8 duty_on;  /* % of duty_length the led is on (0xff mean 100%) */
72755d3b664SFrank Praznik } __packed;
72855d3b664SFrank Praznik 
72955d3b664SFrank Praznik struct sixaxis_rumble {
73055d3b664SFrank Praznik 	__u8 padding;
73155d3b664SFrank Praznik 	__u8 right_duration; /* Right motor duration (0xff means forever) */
73255d3b664SFrank Praznik 	__u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
73355d3b664SFrank Praznik 	__u8 left_duration;    /* Left motor duration (0xff means forever) */
73455d3b664SFrank Praznik 	__u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
73555d3b664SFrank Praznik } __packed;
73655d3b664SFrank Praznik 
73755d3b664SFrank Praznik struct sixaxis_output_report {
73855d3b664SFrank Praznik 	__u8 report_id;
73955d3b664SFrank Praznik 	struct sixaxis_rumble rumble;
74055d3b664SFrank Praznik 	__u8 padding[4];
74155d3b664SFrank Praznik 	__u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
74255d3b664SFrank Praznik 	struct sixaxis_led led[4];    /* LEDx at (4 - x) */
74355d3b664SFrank Praznik 	struct sixaxis_led _reserved; /* LED5, not actually soldered */
74455d3b664SFrank Praznik } __packed;
74555d3b664SFrank Praznik 
74655d3b664SFrank Praznik union sixaxis_output_report_01 {
74755d3b664SFrank Praznik 	struct sixaxis_output_report data;
74855d3b664SFrank Praznik 	__u8 buf[36];
74955d3b664SFrank Praznik };
75055d3b664SFrank Praznik 
751d2d782fcSFrank Praznik static spinlock_t sony_dev_list_lock;
752d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list);
7538025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator);
754d2d782fcSFrank Praznik 
755cc6e0bbbSJiri Kosina struct sony_sc {
756d902f472SFrank Praznik 	spinlock_t lock;
757d2d782fcSFrank Praznik 	struct list_head list_node;
7580a286ef2SSven Eckelmann 	struct hid_device *hdev;
75960781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
760cc6e0bbbSJiri Kosina 	unsigned long quirks;
7610a286ef2SSven Eckelmann 	struct work_struct state_worker;
762d902f472SFrank Praznik 	struct power_supply battery;
7638025087aSFrank Praznik 	int device_id;
764f04d5140SColin Leitner 
7659f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
7669f323b68SSven Eckelmann 	__u8 left;
7679f323b68SSven Eckelmann 	__u8 right;
7689f323b68SSven Eckelmann #endif
7699f323b68SSven Eckelmann 
770d2d782fcSFrank Praznik 	__u8 mac_address[6];
7715f5750d2SFrank Praznik 	__u8 worker_initialized;
772d902f472SFrank Praznik 	__u8 cable_state;
773d902f472SFrank Praznik 	__u8 battery_charging;
774d902f472SFrank Praznik 	__u8 battery_capacity;
77560781cf4SFrank Praznik 	__u8 led_state[MAX_LEDS];
776b3ed458cSFrank Praznik 	__u8 led_delay_on[MAX_LEDS];
777b3ed458cSFrank Praznik 	__u8 led_delay_off[MAX_LEDS];
77860781cf4SFrank Praznik 	__u8 led_count;
779cc6e0bbbSJiri Kosina };
780cc6e0bbbSJiri Kosina 
781078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
782078328daSJiri Kosina 			     unsigned int *rsize)
783078328daSJiri Kosina {
784078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
785078328daSJiri Kosina 	return ps3remote_rdesc;
786078328daSJiri Kosina }
787078328daSJiri Kosina 
788078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
789078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
790078328daSJiri Kosina 			     unsigned long **bit, int *max)
791078328daSJiri Kosina {
792078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
793078328daSJiri Kosina 
794078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
795078328daSJiri Kosina 		return -1;
796078328daSJiri Kosina 
797078328daSJiri Kosina 	switch (usage->collection_index) {
798078328daSJiri Kosina 	case 1:
799078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
800078328daSJiri Kosina 			return -1;
801078328daSJiri Kosina 
802078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
803078328daSJiri Kosina 		if (!key)
804078328daSJiri Kosina 			return -1;
805078328daSJiri Kosina 		break;
806078328daSJiri Kosina 	case 2:
807078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
808078328daSJiri Kosina 			return -1;
809078328daSJiri Kosina 
810078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
811078328daSJiri Kosina 		if (!key)
812078328daSJiri Kosina 			return -1;
813078328daSJiri Kosina 		break;
814078328daSJiri Kosina 	default:
815078328daSJiri Kosina 		return -1;
816078328daSJiri Kosina 	}
817078328daSJiri Kosina 
818078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
819078328daSJiri Kosina 	return 1;
820078328daSJiri Kosina }
821078328daSJiri Kosina 
822078328daSJiri Kosina 
823cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
82473e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
82573e4008dSNikolai Kondrashov 		unsigned int *rsize)
826cc6e0bbbSJiri Kosina {
827cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
828cc6e0bbbSJiri Kosina 
82999d24902SFernando Luis Vázquez Cao 	/*
83099d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
83199d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
83299d24902SFernando Luis Vázquez Cao 	 */
83399d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
83499d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
83599d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
83699d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
83799d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
83899d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
83999d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
840a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
84199d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
842cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
843cc6e0bbbSJiri Kosina 	}
84461ab44beSSimon Wood 
845ed19d8cfSFrank Praznik 	/*
846ed19d8cfSFrank Praznik 	 * The default Dualshock 4 USB descriptor doesn't assign
847ed19d8cfSFrank Praznik 	 * the gyroscope values to corresponding axes so we need a
848ed19d8cfSFrank Praznik 	 * modified one.
849ed19d8cfSFrank Praznik 	 */
850ed19d8cfSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
851ed19d8cfSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
852ed19d8cfSFrank Praznik 		rdesc = dualshock4_usb_rdesc;
853ed19d8cfSFrank Praznik 		*rsize = sizeof(dualshock4_usb_rdesc);
854d829674dSFrank Praznik 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
855d829674dSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
856d829674dSFrank Praznik 		rdesc = dualshock4_bt_rdesc;
857d829674dSFrank Praznik 		*rsize = sizeof(dualshock4_bt_rdesc);
858ed19d8cfSFrank Praznik 	}
859ed19d8cfSFrank Praznik 
86061ab44beSSimon Wood 	/* The HID descriptor exposed over BT has a trailing zero byte */
86161ab44beSSimon Wood 	if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
86261ab44beSSimon Wood 			((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
86361ab44beSSimon Wood 			rdesc[83] == 0x75) {
86461ab44beSSimon Wood 		hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
86561ab44beSSimon Wood 		memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
86661ab44beSSimon Wood 			sizeof(sixaxis_rdesc_fixup));
867e57a67daSMauro Carvalho Chehab 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
868e57a67daSMauro Carvalho Chehab 		   *rsize > sizeof(sixaxis_rdesc_fixup2)) {
869e57a67daSMauro Carvalho Chehab 		hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
870e57a67daSMauro Carvalho Chehab 			 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
871e57a67daSMauro Carvalho Chehab 		*rsize = sizeof(sixaxis_rdesc_fixup2);
872e57a67daSMauro Carvalho Chehab 		memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
87361ab44beSSimon Wood 	}
874078328daSJiri Kosina 
875078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
876078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
877078328daSJiri Kosina 
87873e4008dSNikolai Kondrashov 	return rdesc;
879cc6e0bbbSJiri Kosina }
880cc6e0bbbSJiri Kosina 
881d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
882d902f472SFrank Praznik {
883d902f472SFrank Praznik 	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
884d902f472SFrank Praznik 	unsigned long flags;
885d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
886d902f472SFrank Praznik 
887ad142b9eSFrank Praznik 	/*
888ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
889d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
890d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
891d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
892d902f472SFrank Praznik 	 */
893d902f472SFrank Praznik 	if (rd[30] >= 0xee) {
894d902f472SFrank Praznik 		battery_capacity = 100;
895a43e94a3SFrank Praznik 		battery_charging = !(rd[30] & 0x01);
896d902f472SFrank Praznik 	} else {
897ac3c9a94SFrank Praznik 		__u8 index = rd[30] <= 5 ? rd[30] : 5;
898ac3c9a94SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[index];
899d902f472SFrank Praznik 		battery_charging = 0;
900d902f472SFrank Praznik 	}
901914c5783SFrank Praznik 	cable_state = !(rd[31] & 0x04);
902d902f472SFrank Praznik 
903d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
904d902f472SFrank Praznik 	sc->cable_state = cable_state;
905d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
906d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
907d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
908d902f472SFrank Praznik }
909d902f472SFrank Praznik 
910d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
911d902f472SFrank Praznik {
912e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
913e5606230SFrank Praznik 						struct hid_input, list);
914e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
915d902f472SFrank Praznik 	unsigned long flags;
9166c5f860dSFrank Praznik 	int n, offset;
917d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
918d902f472SFrank Praznik 
919ad142b9eSFrank Praznik 	/*
920ad142b9eSFrank Praznik 	 * Battery and touchpad data starts at byte 30 in the USB report and
9216c5f860dSFrank Praznik 	 * 32 in Bluetooth report.
9226c5f860dSFrank Praznik 	 */
9236c5f860dSFrank Praznik 	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
9246c5f860dSFrank Praznik 
925ad142b9eSFrank Praznik 	/*
926ad142b9eSFrank Praznik 	 * The lower 4 bits of byte 30 contain the battery level
927d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
928d902f472SFrank Praznik 	 */
9296c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
9306c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
931d902f472SFrank Praznik 
932ad142b9eSFrank Praznik 	/*
933ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
9346c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
9356c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
936d902f472SFrank Praznik 	 */
9376c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
938d902f472SFrank Praznik 		battery_charging = 0;
939d902f472SFrank Praznik 	else
940d902f472SFrank Praznik 		battery_charging = 1;
941d902f472SFrank Praznik 
9426c5f860dSFrank Praznik 	if (!cable_state)
9436c5f860dSFrank Praznik 		battery_capacity++;
944d902f472SFrank Praznik 	if (battery_capacity > 10)
9456c5f860dSFrank Praznik 		battery_capacity = 10;
9466c5f860dSFrank Praznik 
947d902f472SFrank Praznik 	battery_capacity *= 10;
948d902f472SFrank Praznik 
949d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
950d902f472SFrank Praznik 	sc->cable_state = cable_state;
951d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
952d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
953d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
954e5606230SFrank Praznik 
9556c5f860dSFrank Praznik 	offset += 5;
9566c5f860dSFrank Praznik 
957ad142b9eSFrank Praznik 	/*
958ad142b9eSFrank Praznik 	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
9596c5f860dSFrank Praznik 	 * and 37 on Bluetooth.
960e5606230SFrank Praznik 	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
961e5606230SFrank Praznik 	 * indicator that is 0 when pressed and 1 when not pressed.
962e5606230SFrank Praznik 	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
963e5606230SFrank Praznik 	 * The data for the second touch is in the same format and immediatly
964e5606230SFrank Praznik 	 * follows the data for the first.
965e5606230SFrank Praznik 	 */
966e5606230SFrank Praznik 	for (n = 0; n < 2; n++) {
967e5606230SFrank Praznik 		__u16 x, y;
968e5606230SFrank Praznik 
969e5606230SFrank Praznik 		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
970e5606230SFrank Praznik 		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
971e5606230SFrank Praznik 
972e5606230SFrank Praznik 		input_mt_slot(input_dev, n);
973e5606230SFrank Praznik 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
974e5606230SFrank Praznik 					!(rd[offset] >> 7));
975e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
976e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
977e5606230SFrank Praznik 
978e5606230SFrank Praznik 		offset += 4;
979e5606230SFrank Praznik 	}
980d902f472SFrank Praznik }
981d902f472SFrank Praznik 
982c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
983c9e4d877SSimon Wood 		__u8 *rd, int size)
984c9e4d877SSimon Wood {
985c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
986c9e4d877SSimon Wood 
987ad142b9eSFrank Praznik 	/*
988ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
989c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
990c9e4d877SSimon Wood 	 */
991fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
992c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
993c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
994c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
995c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
996d902f472SFrank Praznik 
997d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
99868330d83SFrank Praznik 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
99968330d83SFrank Praznik 			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
100068330d83SFrank Praznik 			&& rd[0] == 0x11 && size == 78)) {
1001d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
1002c9e4d877SSimon Wood 	}
1003c9e4d877SSimon Wood 
1004c9e4d877SSimon Wood 	return 0;
1005c9e4d877SSimon Wood }
1006c9e4d877SSimon Wood 
1007f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
1008f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
1009f04d5140SColin Leitner 			unsigned long **bit, int *max)
1010f04d5140SColin Leitner {
1011f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1012f04d5140SColin Leitner 
1013f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
1014f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
1015f04d5140SColin Leitner 
1016f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
1017f04d5140SColin Leitner 			return -1;
1018f04d5140SColin Leitner 
1019f04d5140SColin Leitner 		switch (usage->collection_index) {
1020f04d5140SColin Leitner 		case 1:
1021f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
1022f04d5140SColin Leitner 				return -1;
1023f04d5140SColin Leitner 
1024f04d5140SColin Leitner 			key = buzz_keymap[key];
1025f04d5140SColin Leitner 			if (!key)
1026f04d5140SColin Leitner 				return -1;
1027f04d5140SColin Leitner 			break;
1028f04d5140SColin Leitner 		default:
1029f04d5140SColin Leitner 			return -1;
1030f04d5140SColin Leitner 		}
1031f04d5140SColin Leitner 
1032f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1033f04d5140SColin Leitner 		return 1;
1034f04d5140SColin Leitner 	}
1035f04d5140SColin Leitner 
1036078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1037078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
1038078328daSJiri Kosina 
10396f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
10406f498018SBenjamin Tissoires 	return 0;
1041f04d5140SColin Leitner }
1042f04d5140SColin Leitner 
10435710fabfSAntonio Ospite /*
1044bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1045bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1046bd28ce00SJiri Slaby  * events.
1047bd28ce00SJiri Slaby  */
1048816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1049bd28ce00SJiri Slaby {
1050bd28ce00SJiri Slaby 	int ret;
1051bd28ce00SJiri Slaby 	char *buf = kmalloc(18, GFP_KERNEL);
1052bd28ce00SJiri Slaby 
1053bd28ce00SJiri Slaby 	if (!buf)
1054bd28ce00SJiri Slaby 		return -ENOMEM;
1055bd28ce00SJiri Slaby 
1056cafebc05SBenjamin Tissoires 	ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
1057cafebc05SBenjamin Tissoires 				 HID_REQ_GET_REPORT);
1058f204828aSBenjamin Tissoires 
1059bd28ce00SJiri Slaby 	if (ret < 0)
10604291ee30SJoe Perches 		hid_err(hdev, "can't set operational mode\n");
1061bd28ce00SJiri Slaby 
1062bd28ce00SJiri Slaby 	kfree(buf);
1063bd28ce00SJiri Slaby 
1064bd28ce00SJiri Slaby 	return ret;
1065bd28ce00SJiri Slaby }
1066bd28ce00SJiri Slaby 
1067816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1068f9ce7c28SBastien Nocera {
1069fddb33f2SAntonio Ospite 	unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
1070b0dd72aaSBenjamin Tissoires 	return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
1071b0dd72aaSBenjamin Tissoires 				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
1072f9ce7c28SBastien Nocera }
1073f9ce7c28SBastien Nocera 
1074ad142b9eSFrank Praznik /*
1075ad142b9eSFrank Praznik  * Requesting feature report 0x02 in Bluetooth mode changes the state of the
107668330d83SFrank Praznik  * controller so that it sends full input reports of type 0x11.
107768330d83SFrank Praznik  */
107868330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev)
107968330d83SFrank Praznik {
108068330d83SFrank Praznik 	__u8 buf[37] = { 0 };
108168330d83SFrank Praznik 
108268330d83SFrank Praznik 	return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),
108368330d83SFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1084bd28ce00SJiri Slaby }
1085bd28ce00SJiri Slaby 
10868025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS])
10878025087aSFrank Praznik {
10888025087aSFrank Praznik 	static const __u8 sixaxis_leds[10][4] = {
10898025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x00 },
10908025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x00 },
10918025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x00 },
10928025087aSFrank Praznik 				{ 0x00, 0x00, 0x00, 0x01 },
10938025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x01 },
10948025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x01 },
10958025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x01 },
10968025087aSFrank Praznik 				{ 0x01, 0x00, 0x01, 0x01 },
10978025087aSFrank Praznik 				{ 0x00, 0x01, 0x01, 0x01 },
10988025087aSFrank Praznik 				{ 0x01, 0x01, 0x01, 0x01 }
10998025087aSFrank Praznik 	};
11008025087aSFrank Praznik 
11018025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
11028025087aSFrank Praznik 
11038025087aSFrank Praznik 	if (id < 0)
11048025087aSFrank Praznik 		return;
11058025087aSFrank Praznik 
11068025087aSFrank Praznik 	id %= 10;
11078025087aSFrank Praznik 	memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
11088025087aSFrank Praznik }
11098025087aSFrank Praznik 
11108025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS])
11118025087aSFrank Praznik {
11128025087aSFrank Praznik 	/* The first 4 color/index entries match what the PS4 assigns */
11138025087aSFrank Praznik 	static const __u8 color_code[7][3] = {
11148025087aSFrank Praznik 			/* Blue   */	{ 0x00, 0x00, 0x01 },
11158025087aSFrank Praznik 			/* Red	  */	{ 0x01, 0x00, 0x00 },
11168025087aSFrank Praznik 			/* Green  */	{ 0x00, 0x01, 0x00 },
11178025087aSFrank Praznik 			/* Pink   */	{ 0x02, 0x00, 0x01 },
11188025087aSFrank Praznik 			/* Orange */	{ 0x02, 0x01, 0x00 },
11198025087aSFrank Praznik 			/* Teal   */	{ 0x00, 0x01, 0x01 },
11208025087aSFrank Praznik 			/* White  */	{ 0x01, 0x01, 0x01 }
11218025087aSFrank Praznik 	};
11228025087aSFrank Praznik 
11238025087aSFrank Praznik 	BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
11248025087aSFrank Praznik 
11258025087aSFrank Praznik 	if (id < 0)
11268025087aSFrank Praznik 		return;
11278025087aSFrank Praznik 
11288025087aSFrank Praznik 	id %= 7;
11298025087aSFrank Praznik 	memcpy(values, color_code[id], sizeof(color_code[id]));
11308025087aSFrank Praznik }
11318025087aSFrank Praznik 
113260781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
1133f04d5140SColin Leitner {
1134f04d5140SColin Leitner 	struct list_head *report_list =
1135f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1136f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1137f04d5140SColin Leitner 		struct hid_report, list);
1138f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
1139f04d5140SColin Leitner 
1140f04d5140SColin Leitner 	value[0] = 0x00;
114160781cf4SFrank Praznik 	value[1] = leds[0] ? 0xff : 0x00;
114260781cf4SFrank Praznik 	value[2] = leds[1] ? 0xff : 0x00;
114360781cf4SFrank Praznik 	value[3] = leds[2] ? 0xff : 0x00;
114460781cf4SFrank Praznik 	value[4] = leds[3] ? 0xff : 0x00;
1145f04d5140SColin Leitner 	value[5] = 0x00;
1146f04d5140SColin Leitner 	value[6] = 0x00;
1147f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1148f04d5140SColin Leitner }
1149f04d5140SColin Leitner 
1150fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count)
11510a286ef2SSven Eckelmann {
115260781cf4SFrank Praznik 	int n;
11530a286ef2SSven Eckelmann 
115460781cf4SFrank Praznik 	BUG_ON(count > MAX_LEDS);
115560781cf4SFrank Praznik 
1156fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER && count == 4) {
1157fa57a810SFrank Praznik 		buzz_set_leds(sc->hdev, leds);
1158fee4e2d5SFrank Praznik 	} else {
115960781cf4SFrank Praznik 		for (n = 0; n < count; n++)
1160fa57a810SFrank Praznik 			sc->led_state[n] = leds[n];
1161fa57a810SFrank Praznik 		schedule_work(&sc->state_worker);
11620a286ef2SSven Eckelmann 	}
11630a286ef2SSven Eckelmann }
11640a286ef2SSven Eckelmann 
1165c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1166f04d5140SColin Leitner 				    enum led_brightness value)
1167f04d5140SColin Leitner {
1168f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1169f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1170f04d5140SColin Leitner 	struct sony_sc *drv_data;
1171f04d5140SColin Leitner 
1172f04d5140SColin Leitner 	int n;
1173b3ed458cSFrank Praznik 	int force_update;
1174f04d5140SColin Leitner 
1175f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
11762251b85fSSven Eckelmann 	if (!drv_data) {
1177f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1178f04d5140SColin Leitner 		return;
1179f04d5140SColin Leitner 	}
1180f04d5140SColin Leitner 
1181b3ed458cSFrank Praznik 	/*
1182b3ed458cSFrank Praznik 	 * The Sixaxis on USB will override any LED settings sent to it
1183b3ed458cSFrank Praznik 	 * and keep flashing all of the LEDs until the PS button is pressed.
1184b3ed458cSFrank Praznik 	 * Updates, even if redundant, must be always be sent to the
1185b3ed458cSFrank Praznik 	 * controller to avoid having to toggle the state of an LED just to
1186b3ed458cSFrank Praznik 	 * stop the flashing later on.
1187b3ed458cSFrank Praznik 	 */
1188b3ed458cSFrank Praznik 	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1189b3ed458cSFrank Praznik 
119060781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1191b3ed458cSFrank Praznik 		if (led == drv_data->leds[n] && (force_update ||
1192b3ed458cSFrank Praznik 			(value != drv_data->led_state[n] ||
1193b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] ||
1194b3ed458cSFrank Praznik 			drv_data->led_delay_off[n]))) {
1195b3ed458cSFrank Praznik 
119660781cf4SFrank Praznik 			drv_data->led_state[n] = value;
1197b3ed458cSFrank Praznik 
1198b3ed458cSFrank Praznik 			/* Setting the brightness stops the blinking */
1199b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] = 0;
1200b3ed458cSFrank Praznik 			drv_data->led_delay_off[n] = 0;
1201b3ed458cSFrank Praznik 
1202fa57a810SFrank Praznik 			sony_set_leds(drv_data, drv_data->led_state,
1203fa57a810SFrank Praznik 					drv_data->led_count);
1204f04d5140SColin Leitner 			break;
1205f04d5140SColin Leitner 		}
1206f04d5140SColin Leitner 	}
1207f04d5140SColin Leitner }
1208f04d5140SColin Leitner 
1209c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1210f04d5140SColin Leitner {
1211f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1212f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1213f04d5140SColin Leitner 	struct sony_sc *drv_data;
1214f04d5140SColin Leitner 
1215f04d5140SColin Leitner 	int n;
1216f04d5140SColin Leitner 
1217f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
12182251b85fSSven Eckelmann 	if (!drv_data) {
1219f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1220f04d5140SColin Leitner 		return LED_OFF;
1221f04d5140SColin Leitner 	}
1222f04d5140SColin Leitner 
122360781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
12247db7504aSSimon Wood 		if (led == drv_data->leds[n])
12257db7504aSSimon Wood 			return drv_data->led_state[n];
1226f04d5140SColin Leitner 	}
1227f04d5140SColin Leitner 
12287db7504aSSimon Wood 	return LED_OFF;
1229f04d5140SColin Leitner }
1230f04d5140SColin Leitner 
1231b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1232b3ed458cSFrank Praznik 				unsigned long *delay_off)
1233b3ed458cSFrank Praznik {
1234b3ed458cSFrank Praznik 	struct device *dev = led->dev->parent;
1235b3ed458cSFrank Praznik 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1236b3ed458cSFrank Praznik 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
1237b3ed458cSFrank Praznik 	int n;
1238b3ed458cSFrank Praznik 	__u8 new_on, new_off;
1239b3ed458cSFrank Praznik 
1240b3ed458cSFrank Praznik 	if (!drv_data) {
1241b3ed458cSFrank Praznik 		hid_err(hdev, "No device data\n");
1242b3ed458cSFrank Praznik 		return -EINVAL;
1243b3ed458cSFrank Praznik 	}
1244b3ed458cSFrank Praznik 
1245b3ed458cSFrank Praznik 	/* Max delay is 255 deciseconds or 2550 milliseconds */
1246b3ed458cSFrank Praznik 	if (*delay_on > 2550)
1247b3ed458cSFrank Praznik 		*delay_on = 2550;
1248b3ed458cSFrank Praznik 	if (*delay_off > 2550)
1249b3ed458cSFrank Praznik 		*delay_off = 2550;
1250b3ed458cSFrank Praznik 
1251b3ed458cSFrank Praznik 	/* Blink at 1 Hz if both values are zero */
1252b3ed458cSFrank Praznik 	if (!*delay_on && !*delay_off)
1253b3ed458cSFrank Praznik 		*delay_on = *delay_off = 500;
1254b3ed458cSFrank Praznik 
1255b3ed458cSFrank Praznik 	new_on = *delay_on / 10;
1256b3ed458cSFrank Praznik 	new_off = *delay_off / 10;
1257b3ed458cSFrank Praznik 
1258b3ed458cSFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1259b3ed458cSFrank Praznik 		if (led == drv_data->leds[n])
1260b3ed458cSFrank Praznik 			break;
1261b3ed458cSFrank Praznik 	}
1262b3ed458cSFrank Praznik 
1263b3ed458cSFrank Praznik 	/* This LED is not registered on this device */
1264b3ed458cSFrank Praznik 	if (n >= drv_data->led_count)
1265b3ed458cSFrank Praznik 		return -EINVAL;
1266b3ed458cSFrank Praznik 
1267b3ed458cSFrank Praznik 	/* Don't schedule work if the values didn't change */
1268b3ed458cSFrank Praznik 	if (new_on != drv_data->led_delay_on[n] ||
1269b3ed458cSFrank Praznik 		new_off != drv_data->led_delay_off[n]) {
1270b3ed458cSFrank Praznik 		drv_data->led_delay_on[n] = new_on;
1271b3ed458cSFrank Praznik 		drv_data->led_delay_off[n] = new_off;
1272b3ed458cSFrank Praznik 		schedule_work(&drv_data->state_worker);
1273b3ed458cSFrank Praznik 	}
1274b3ed458cSFrank Praznik 
1275b3ed458cSFrank Praznik 	return 0;
1276b3ed458cSFrank Praznik }
1277b3ed458cSFrank Praznik 
1278fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc)
12790a286ef2SSven Eckelmann {
12800a286ef2SSven Eckelmann 	struct led_classdev *led;
12810a286ef2SSven Eckelmann 	int n;
12820a286ef2SSven Eckelmann 
1283fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
12840a286ef2SSven Eckelmann 
1285fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
1286fa57a810SFrank Praznik 		led = sc->leds[n];
1287fa57a810SFrank Praznik 		sc->leds[n] = NULL;
12880a286ef2SSven Eckelmann 		if (!led)
12890a286ef2SSven Eckelmann 			continue;
12900a286ef2SSven Eckelmann 		led_classdev_unregister(led);
12910a286ef2SSven Eckelmann 		kfree(led);
12920a286ef2SSven Eckelmann 	}
129360781cf4SFrank Praznik 
1294fa57a810SFrank Praznik 	sc->led_count = 0;
12950a286ef2SSven Eckelmann }
12960a286ef2SSven Eckelmann 
1297fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc)
1298f04d5140SColin Leitner {
1299fa57a810SFrank Praznik 	struct hid_device *hdev = sc->hdev;
130040e32ee6SJiri Kosina 	int n, ret = 0;
1301b3ed458cSFrank Praznik 	int use_ds4_names;
130240e32ee6SJiri Kosina 	struct led_classdev *led;
130340e32ee6SJiri Kosina 	size_t name_sz;
130440e32ee6SJiri Kosina 	char *name;
13050a286ef2SSven Eckelmann 	size_t name_len;
13060a286ef2SSven Eckelmann 	const char *name_fmt;
1307b3ed458cSFrank Praznik 	static const char * const ds4_name_str[] = { "red", "green", "blue",
1308b3ed458cSFrank Praznik 						  "global" };
13098025087aSFrank Praznik 	__u8 initial_values[MAX_LEDS] = { 0 };
1310b3ed458cSFrank Praznik 	__u8 max_brightness[MAX_LEDS] = { 1 };
1311b3ed458cSFrank Praznik 	__u8 use_hw_blink[MAX_LEDS] = { 0 };
1312f04d5140SColin Leitner 
1313fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1314f04d5140SColin Leitner 
1315fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER) {
1316fa57a810SFrank Praznik 		sc->led_count = 4;
1317b3ed458cSFrank Praznik 		use_ds4_names = 0;
13180a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
13190a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
13209446edb9SKees Cook 		/* Validate expected report characteristics. */
13219446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
13229446edb9SKees Cook 			return -ENODEV;
1323fa57a810SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
13248025087aSFrank Praznik 		dualshock4_set_leds_from_id(sc->device_id, initial_values);
1325b3ed458cSFrank Praznik 		initial_values[3] = 1;
1326b3ed458cSFrank Praznik 		sc->led_count = 4;
1327b3ed458cSFrank Praznik 		memset(max_brightness, 255, 3);
1328b3ed458cSFrank Praznik 		use_hw_blink[3] = 1;
1329b3ed458cSFrank Praznik 		use_ds4_names = 1;
133061ebca93SFrank Praznik 		name_len = 0;
133161ebca93SFrank Praznik 		name_fmt = "%s:%s";
133260781cf4SFrank Praznik 	} else {
13338025087aSFrank Praznik 		sixaxis_set_leds_from_id(sc->device_id, initial_values);
1334fa57a810SFrank Praznik 		sc->led_count = 4;
1335b3ed458cSFrank Praznik 		memset(use_hw_blink, 1, 4);
1336b3ed458cSFrank Praznik 		use_ds4_names = 0;
133761ebca93SFrank Praznik 		name_len = strlen("::sony#");
133861ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
133960781cf4SFrank Praznik 	}
134060781cf4SFrank Praznik 
1341ad142b9eSFrank Praznik 	/*
1342ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1343f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1344ad142b9eSFrank Praznik 	 * LEDs to on
1345ad142b9eSFrank Praznik 	 */
1346fa57a810SFrank Praznik 	sony_set_leds(sc, initial_values, sc->led_count);
1347f04d5140SColin Leitner 
13480a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1349f04d5140SColin Leitner 
1350fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
135161ebca93SFrank Praznik 
1352b3ed458cSFrank Praznik 		if (use_ds4_names)
1353b3ed458cSFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
135461ebca93SFrank Praznik 
1355f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1356f04d5140SColin Leitner 		if (!led) {
1357f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
13588cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1359f04d5140SColin Leitner 			goto error_leds;
1360f04d5140SColin Leitner 		}
1361f04d5140SColin Leitner 
1362f04d5140SColin Leitner 		name = (void *)(&led[1]);
1363b3ed458cSFrank Praznik 		if (use_ds4_names)
1364b3ed458cSFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1365b3ed458cSFrank Praznik 			ds4_name_str[n]);
136661ebca93SFrank Praznik 		else
13670a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1368f04d5140SColin Leitner 		led->name = name;
13698025087aSFrank Praznik 		led->brightness = initial_values[n];
1370b3ed458cSFrank Praznik 		led->max_brightness = max_brightness[n];
1371c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1372c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1373f04d5140SColin Leitner 
1374b3ed458cSFrank Praznik 		if (use_hw_blink[n])
1375b3ed458cSFrank Praznik 			led->blink_set = sony_led_blink_set;
1376b3ed458cSFrank Praznik 
13778025087aSFrank Praznik 		sc->leds[n] = led;
13788025087aSFrank Praznik 
13798cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
13808cd5fcdaSJulia Lawall 		if (ret) {
1381f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
13828025087aSFrank Praznik 			sc->leds[n] = NULL;
1383f04d5140SColin Leitner 			kfree(led);
1384f04d5140SColin Leitner 			goto error_leds;
1385f04d5140SColin Leitner 		}
1386f04d5140SColin Leitner 	}
1387f04d5140SColin Leitner 
1388f04d5140SColin Leitner 	return ret;
1389f04d5140SColin Leitner 
1390f04d5140SColin Leitner error_leds:
1391fa57a810SFrank Praznik 	sony_leds_remove(sc);
1392f04d5140SColin Leitner 
1393f04d5140SColin Leitner 	return ret;
1394f04d5140SColin Leitner }
1395f04d5140SColin Leitner 
1396cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
1397a08c22c0SSven Eckelmann {
139892b5c411SSven Eckelmann 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1399b3ed458cSFrank Praznik 	int n;
140055d3b664SFrank Praznik 	union sixaxis_output_report_01 report = {
140155d3b664SFrank Praznik 		.buf = {
1402a08c22c0SSven Eckelmann 			0x01,
1403a08c22c0SSven Eckelmann 			0x00, 0xff, 0x00, 0xff, 0x00,
14040a286ef2SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00,
1405a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1406a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1407a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1408a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1409a08c22c0SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00
141055d3b664SFrank Praznik 		}
1411a08c22c0SSven Eckelmann 	};
14129f323b68SSven Eckelmann 
14130a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
141455d3b664SFrank Praznik 	report.data.rumble.right_motor_on = sc->right ? 1 : 0;
141555d3b664SFrank Praznik 	report.data.rumble.left_motor_force = sc->left;
14160a286ef2SSven Eckelmann #endif
14170a286ef2SSven Eckelmann 
141855d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[0] << 1;
141955d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[1] << 2;
142055d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[2] << 3;
142155d3b664SFrank Praznik 	report.data.leds_bitmap |= sc->led_state[3] << 4;
14229f323b68SSven Eckelmann 
142388f6576fSSimon Wood 	/* Set flag for all leds off, required for 3rd party INTEC controller */
142488f6576fSSimon Wood 	if ((report.data.leds_bitmap & 0x1E) == 0)
142588f6576fSSimon Wood 		report.data.leds_bitmap |= 0x20;
142688f6576fSSimon Wood 
1427b3ed458cSFrank Praznik 	/*
1428b3ed458cSFrank Praznik 	 * The LEDs in the report are indexed in reverse order to their
1429b3ed458cSFrank Praznik 	 * corresponding light on the controller.
1430b3ed458cSFrank Praznik 	 * Index 0 = LED 4, index 1 = LED 3, etc...
1431b3ed458cSFrank Praznik 	 *
1432b3ed458cSFrank Praznik 	 * In the case of both delay values being zero (blinking disabled) the
1433b3ed458cSFrank Praznik 	 * default report values should be used or the controller LED will be
1434b3ed458cSFrank Praznik 	 * always off.
1435b3ed458cSFrank Praznik 	 */
1436b3ed458cSFrank Praznik 	for (n = 0; n < 4; n++) {
1437b3ed458cSFrank Praznik 		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
1438b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_off = sc->led_delay_off[n];
1439b3ed458cSFrank Praznik 			report.data.led[3 - n].duty_on = sc->led_delay_on[n];
1440b3ed458cSFrank Praznik 		}
1441b3ed458cSFrank Praznik 	}
1442b3ed458cSFrank Praznik 
144355d3b664SFrank Praznik 	hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
144455d3b664SFrank Praznik 			sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
14459f323b68SSven Eckelmann }
14469f323b68SSven Eckelmann 
14470bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
14480bd88dd3SFrank Praznik {
14490bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
14500da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
145148220237SFrank Praznik 	int offset;
14520da8ea65SFrank Praznik 
1453fdcf105dSFrank Praznik 	__u8 buf[78] = { 0 };
145448220237SFrank Praznik 
1455fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
145648220237SFrank Praznik 		buf[0] = 0x05;
1457b3ed458cSFrank Praznik 		buf[1] = 0xFF;
145848220237SFrank Praznik 		offset = 4;
1459fdcf105dSFrank Praznik 	} else {
1460fdcf105dSFrank Praznik 		buf[0] = 0x11;
1461fdcf105dSFrank Praznik 		buf[1] = 0xB0;
1462fdcf105dSFrank Praznik 		buf[3] = 0x0F;
1463fdcf105dSFrank Praznik 		offset = 6;
1464fdcf105dSFrank Praznik 	}
14650bd88dd3SFrank Praznik 
14660bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
146748220237SFrank Praznik 	buf[offset++] = sc->right;
146848220237SFrank Praznik 	buf[offset++] = sc->left;
146948220237SFrank Praznik #else
147048220237SFrank Praznik 	offset += 2;
14710bd88dd3SFrank Praznik #endif
14720bd88dd3SFrank Praznik 
1473b3ed458cSFrank Praznik 	/* LED 3 is the global control */
1474b3ed458cSFrank Praznik 	if (sc->led_state[3]) {
147548220237SFrank Praznik 		buf[offset++] = sc->led_state[0];
147648220237SFrank Praznik 		buf[offset++] = sc->led_state[1];
147748220237SFrank Praznik 		buf[offset++] = sc->led_state[2];
1478b3ed458cSFrank Praznik 	} else {
1479b3ed458cSFrank Praznik 		offset += 3;
1480b3ed458cSFrank Praznik 	}
1481b3ed458cSFrank Praznik 
1482b3ed458cSFrank Praznik 	/* If both delay values are zero the DualShock 4 disables blinking. */
1483b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_on[3];
1484b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_off[3];
148560781cf4SFrank Praznik 
1486fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1487fdcf105dSFrank Praznik 		hid_hw_output_report(hdev, buf, 32);
1488fdcf105dSFrank Praznik 	else
1489fdcf105dSFrank Praznik 		hid_hw_raw_request(hdev, 0x11, buf, 78,
1490fdcf105dSFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
14910bd88dd3SFrank Praznik }
14920bd88dd3SFrank Praznik 
14930a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
14949f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
14959f323b68SSven Eckelmann 			    struct ff_effect *effect)
14969f323b68SSven Eckelmann {
1497a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
14989f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
1499a08c22c0SSven Eckelmann 
1500a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
1501a08c22c0SSven Eckelmann 		return 0;
1502a08c22c0SSven Eckelmann 
15039f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
15040bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
1505a08c22c0SSven Eckelmann 
150692b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
15079f323b68SSven Eckelmann 	return 0;
1508a08c22c0SSven Eckelmann }
1509a08c22c0SSven Eckelmann 
1510fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1511a08c22c0SSven Eckelmann {
1512fa57a810SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1513a08c22c0SSven Eckelmann 						struct hid_input, list);
1514a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
1515a08c22c0SSven Eckelmann 
1516a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1517a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1518a08c22c0SSven Eckelmann }
1519a08c22c0SSven Eckelmann 
1520a08c22c0SSven Eckelmann #else
1521fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1522a08c22c0SSven Eckelmann {
1523a08c22c0SSven Eckelmann 	return 0;
1524a08c22c0SSven Eckelmann }
15259f323b68SSven Eckelmann 
1526a08c22c0SSven Eckelmann #endif
1527a08c22c0SSven Eckelmann 
1528d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
1529d902f472SFrank Praznik 				     enum power_supply_property psp,
1530d902f472SFrank Praznik 				     union power_supply_propval *val)
1531c4e1ddf2SFrank Praznik {
1532d902f472SFrank Praznik 	struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
1533d902f472SFrank Praznik 	unsigned long flags;
1534d902f472SFrank Praznik 	int ret = 0;
1535d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
1536c4e1ddf2SFrank Praznik 
1537d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1538d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
1539d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
1540d902f472SFrank Praznik 	cable_state = sc->cable_state;
1541d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1542c4e1ddf2SFrank Praznik 
1543d902f472SFrank Praznik 	switch (psp) {
1544d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
1545d902f472SFrank Praznik 		val->intval = 1;
1546d902f472SFrank Praznik 		break;
1547d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
1548d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1549d902f472SFrank Praznik 		break;
1550d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
1551d902f472SFrank Praznik 		val->intval = battery_capacity;
1552d902f472SFrank Praznik 		break;
1553d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
1554d902f472SFrank Praznik 		if (battery_charging)
1555d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
1556d902f472SFrank Praznik 		else
1557d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
1558d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
1559d902f472SFrank Praznik 			else
1560d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1561d902f472SFrank Praznik 		break;
1562d902f472SFrank Praznik 	default:
1563d902f472SFrank Praznik 		ret = -EINVAL;
1564d902f472SFrank Praznik 		break;
1565c4e1ddf2SFrank Praznik 	}
1566d902f472SFrank Praznik 	return ret;
1567d902f472SFrank Praznik }
1568d902f472SFrank Praznik 
1569d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc)
1570d902f472SFrank Praznik {
1571d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1572d902f472SFrank Praznik 	int ret;
1573d902f472SFrank Praznik 
1574ad142b9eSFrank Praznik 	/*
1575ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
1576d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
1577d9a293a9SFrank Praznik 	 */
1578d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
1579d9a293a9SFrank Praznik 
1580d902f472SFrank Praznik 	sc->battery.properties = sony_battery_props;
1581d902f472SFrank Praznik 	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
1582d902f472SFrank Praznik 	sc->battery.get_property = sony_battery_get_property;
1583d902f472SFrank Praznik 	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1584d902f472SFrank Praznik 	sc->battery.use_for_apm = 0;
1585314531f1SFrank Praznik 	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR",
1586314531f1SFrank Praznik 				     sc->mac_address);
1587d902f472SFrank Praznik 	if (!sc->battery.name)
1588d902f472SFrank Praznik 		return -ENOMEM;
1589d902f472SFrank Praznik 
1590d902f472SFrank Praznik 	ret = power_supply_register(&hdev->dev, &sc->battery);
1591d902f472SFrank Praznik 	if (ret) {
1592d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
1593d902f472SFrank Praznik 		goto err_free;
1594d902f472SFrank Praznik 	}
1595d902f472SFrank Praznik 
1596d902f472SFrank Praznik 	power_supply_powers(&sc->battery, &hdev->dev);
1597d902f472SFrank Praznik 	return 0;
1598d902f472SFrank Praznik 
1599d902f472SFrank Praznik err_free:
1600d902f472SFrank Praznik 	kfree(sc->battery.name);
1601d902f472SFrank Praznik 	sc->battery.name = NULL;
1602d902f472SFrank Praznik 	return ret;
1603d902f472SFrank Praznik }
1604d902f472SFrank Praznik 
1605d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
1606d902f472SFrank Praznik {
1607d902f472SFrank Praznik 	if (!sc->battery.name)
1608d902f472SFrank Praznik 		return;
1609d902f472SFrank Praznik 
1610d902f472SFrank Praznik 	power_supply_unregister(&sc->battery);
1611d902f472SFrank Praznik 	kfree(sc->battery.name);
1612d902f472SFrank Praznik 	sc->battery.name = NULL;
1613d902f472SFrank Praznik }
1614d902f472SFrank Praznik 
1615e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1616e5606230SFrank Praznik 					int w, int h)
1617e5606230SFrank Praznik {
1618e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1619e5606230SFrank Praznik 						struct hid_input, list);
1620e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
1621e5606230SFrank Praznik 	int ret;
1622e5606230SFrank Praznik 
1623e5606230SFrank Praznik 	ret = input_mt_init_slots(input_dev, touch_count, 0);
1624e5606230SFrank Praznik 	if (ret < 0) {
1625e5606230SFrank Praznik 		hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
1626e5606230SFrank Praznik 		return ret;
1627e5606230SFrank Praznik 	}
1628e5606230SFrank Praznik 
1629e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1630e5606230SFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1631e5606230SFrank Praznik 
1632c4e1ddf2SFrank Praznik 	return 0;
1633c4e1ddf2SFrank Praznik }
1634e5606230SFrank Praznik 
1635d2d782fcSFrank Praznik /*
1636d2d782fcSFrank Praznik  * If a controller is plugged in via USB while already connected via Bluetooth
1637d2d782fcSFrank Praznik  * it will show up as two devices. A global list of connected controllers and
1638d2d782fcSFrank Praznik  * their MAC addresses is maintained to ensure that a device is only connected
1639d2d782fcSFrank Praznik  * once.
1640d2d782fcSFrank Praznik  */
1641d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc)
1642d2d782fcSFrank Praznik {
1643d2d782fcSFrank Praznik 	struct sony_sc *entry;
1644d2d782fcSFrank Praznik 	unsigned long flags;
1645d2d782fcSFrank Praznik 	int ret;
1646d2d782fcSFrank Praznik 
1647d2d782fcSFrank Praznik 	spin_lock_irqsave(&sony_dev_list_lock, flags);
1648d2d782fcSFrank Praznik 
1649d2d782fcSFrank Praznik 	list_for_each_entry(entry, &sony_device_list, list_node) {
1650d2d782fcSFrank Praznik 		ret = memcmp(sc->mac_address, entry->mac_address,
1651d2d782fcSFrank Praznik 				sizeof(sc->mac_address));
1652d2d782fcSFrank Praznik 		if (!ret) {
1653d2d782fcSFrank Praznik 			ret = -EEXIST;
1654d2d782fcSFrank Praznik 			hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",
1655d2d782fcSFrank Praznik 				sc->mac_address);
1656d2d782fcSFrank Praznik 			goto unlock;
1657d2d782fcSFrank Praznik 		}
1658c4e1ddf2SFrank Praznik 	}
1659c4e1ddf2SFrank Praznik 
1660d2d782fcSFrank Praznik 	ret = 0;
1661d2d782fcSFrank Praznik 	list_add(&(sc->list_node), &sony_device_list);
1662c4e1ddf2SFrank Praznik 
1663d2d782fcSFrank Praznik unlock:
1664d2d782fcSFrank Praznik 	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1665d2d782fcSFrank Praznik 	return ret;
1666d2d782fcSFrank Praznik }
1667d2d782fcSFrank Praznik 
1668d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc)
1669d2d782fcSFrank Praznik {
1670d2d782fcSFrank Praznik 	unsigned long flags;
1671d2d782fcSFrank Praznik 
1672d2d782fcSFrank Praznik 	if (sc->list_node.next) {
1673d2d782fcSFrank Praznik 		spin_lock_irqsave(&sony_dev_list_lock, flags);
1674d2d782fcSFrank Praznik 		list_del(&(sc->list_node));
1675d2d782fcSFrank Praznik 		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1676d2d782fcSFrank Praznik 	}
1677d2d782fcSFrank Praznik }
1678d2d782fcSFrank Praznik 
1679d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc)
1680d2d782fcSFrank Praznik {
1681d2d782fcSFrank Praznik 	int ret;
1682d2d782fcSFrank Praznik 
1683d2d782fcSFrank Praznik 	/* HIDP stores the device MAC address as a string in the uniq field. */
1684d2d782fcSFrank Praznik 	ret = strlen(sc->hdev->uniq);
1685d2d782fcSFrank Praznik 	if (ret != 17)
1686c4e1ddf2SFrank Praznik 		return -EINVAL;
1687d2d782fcSFrank Praznik 
1688d2d782fcSFrank Praznik 	ret = sscanf(sc->hdev->uniq,
1689d2d782fcSFrank Praznik 		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1690d2d782fcSFrank Praznik 		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
1691d2d782fcSFrank Praznik 		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
1692d2d782fcSFrank Praznik 
1693d2d782fcSFrank Praznik 	if (ret != 6)
1694d2d782fcSFrank Praznik 		return -EINVAL;
1695d2d782fcSFrank Praznik 
1696d2d782fcSFrank Praznik 	return 0;
1697c4e1ddf2SFrank Praznik }
1698c4e1ddf2SFrank Praznik 
1699d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc)
1700d2d782fcSFrank Praznik {
1701d2d782fcSFrank Praznik 	int n, ret;
1702d2d782fcSFrank Praznik 
1703d2d782fcSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
1704d2d782fcSFrank Praznik 	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
1705d2d782fcSFrank Praznik 		/*
1706d2d782fcSFrank Praznik 		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
1707d2d782fcSFrank Praznik 		 * address from the uniq string where HIDP stores it.
1708d2d782fcSFrank Praznik 		 * As uniq cannot be guaranteed to be a MAC address in all cases
1709d2d782fcSFrank Praznik 		 * a failure of this function should not prevent the connection.
1710d2d782fcSFrank Praznik 		 */
1711d2d782fcSFrank Praznik 		if (sony_get_bt_devaddr(sc) < 0) {
1712d2d782fcSFrank Praznik 			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");
1713d2d782fcSFrank Praznik 			return 0;
1714d2d782fcSFrank Praznik 		}
1715d2d782fcSFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
1716d2d782fcSFrank Praznik 		__u8 buf[7];
1717d2d782fcSFrank Praznik 
1718d2d782fcSFrank Praznik 		/*
1719d2d782fcSFrank Praznik 		 * The MAC address of a DS4 controller connected via USB can be
1720d2d782fcSFrank Praznik 		 * retrieved with feature report 0x81. The address begins at
1721d2d782fcSFrank Praznik 		 * offset 1.
1722d2d782fcSFrank Praznik 		 */
1723d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf),
1724d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1725d2d782fcSFrank Praznik 
1726d2d782fcSFrank Praznik 		if (ret != 7) {
1727d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
1728d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1729d2d782fcSFrank Praznik 		}
1730d2d782fcSFrank Praznik 
1731d2d782fcSFrank Praznik 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
1732d2d782fcSFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1733d2d782fcSFrank Praznik 		__u8 buf[18];
1734d2d782fcSFrank Praznik 
1735d2d782fcSFrank Praznik 		/*
1736d2d782fcSFrank Praznik 		 * The MAC address of a Sixaxis controller connected via USB can
1737d2d782fcSFrank Praznik 		 * be retrieved with feature report 0xf2. The address begins at
1738d2d782fcSFrank Praznik 		 * offset 4.
1739d2d782fcSFrank Praznik 		 */
1740d2d782fcSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf),
1741d2d782fcSFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1742d2d782fcSFrank Praznik 
1743d2d782fcSFrank Praznik 		if (ret != 18) {
1744d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");
1745d2d782fcSFrank Praznik 			return ret < 0 ? ret : -EINVAL;
1746d2d782fcSFrank Praznik 		}
1747d2d782fcSFrank Praznik 
1748d2d782fcSFrank Praznik 		/*
1749d2d782fcSFrank Praznik 		 * The Sixaxis device MAC in the report is big-endian and must
1750d2d782fcSFrank Praznik 		 * be byte-swapped.
1751d2d782fcSFrank Praznik 		 */
1752d2d782fcSFrank Praznik 		for (n = 0; n < 6; n++)
1753d2d782fcSFrank Praznik 			sc->mac_address[5-n] = buf[4+n];
1754d2d782fcSFrank Praznik 	} else {
1755d2d782fcSFrank Praznik 		return 0;
1756d2d782fcSFrank Praznik 	}
1757d2d782fcSFrank Praznik 
1758d2d782fcSFrank Praznik 	return sony_check_add_dev_list(sc);
1759d2d782fcSFrank Praznik }
1760d2d782fcSFrank Praznik 
17618025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc)
17628025087aSFrank Praznik {
17638025087aSFrank Praznik 	int ret;
17648025087aSFrank Praznik 
17658025087aSFrank Praznik 	/*
17668025087aSFrank Praznik 	 * Only DualShock 4 or Sixaxis controllers get an id.
17678025087aSFrank Praznik 	 * All others are set to -1.
17688025087aSFrank Praznik 	 */
17698025087aSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
17708025087aSFrank Praznik 	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
17718025087aSFrank Praznik 		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
17728025087aSFrank Praznik 					GFP_KERNEL);
17738025087aSFrank Praznik 		if (ret < 0) {
17748025087aSFrank Praznik 			sc->device_id = -1;
17758025087aSFrank Praznik 			return ret;
17768025087aSFrank Praznik 		}
17778025087aSFrank Praznik 		sc->device_id = ret;
17788025087aSFrank Praznik 	} else {
17798025087aSFrank Praznik 		sc->device_id = -1;
17808025087aSFrank Praznik 	}
17818025087aSFrank Praznik 
17828025087aSFrank Praznik 	return 0;
17838025087aSFrank Praznik }
17848025087aSFrank Praznik 
17858025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc)
17868025087aSFrank Praznik {
17878025087aSFrank Praznik 	if (sc->device_id >= 0) {
17888025087aSFrank Praznik 		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
17898025087aSFrank Praznik 		sc->device_id = -1;
17908025087aSFrank Praznik 	}
17918025087aSFrank Praznik }
17928025087aSFrank Praznik 
179346262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc,
179446262047SFrank Praznik 					void (*worker)(struct work_struct *))
179546262047SFrank Praznik {
179646262047SFrank Praznik 	if (!sc->worker_initialized)
179746262047SFrank Praznik 		INIT_WORK(&sc->state_worker, worker);
179846262047SFrank Praznik 
179946262047SFrank Praznik 	sc->worker_initialized = 1;
180046262047SFrank Praznik }
180146262047SFrank Praznik 
180246262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc)
180346262047SFrank Praznik {
180446262047SFrank Praznik 	if (sc->worker_initialized)
180546262047SFrank Praznik 		cancel_work_sync(&sc->state_worker);
180646262047SFrank Praznik }
1807d2d782fcSFrank Praznik 
1808bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1809bd28ce00SJiri Slaby {
1810bd28ce00SJiri Slaby 	int ret;
1811cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
1812cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
1813f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
1814cc6e0bbbSJiri Kosina 
1815abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
1816cc6e0bbbSJiri Kosina 	if (sc == NULL) {
18174291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
1818cc6e0bbbSJiri Kosina 		return -ENOMEM;
1819cc6e0bbbSJiri Kosina 	}
1820cc6e0bbbSJiri Kosina 
1821cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
1822cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
18230a286ef2SSven Eckelmann 	sc->hdev = hdev;
1824bd28ce00SJiri Slaby 
1825bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
1826bd28ce00SJiri Slaby 	if (ret) {
18274291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
1828abf832bfSBenjamin Tissoires 		return ret;
1829bd28ce00SJiri Slaby 	}
1830bd28ce00SJiri Slaby 
1831f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
1832f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1833*50764650SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER)
1834f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1835f04d5140SColin Leitner 
1836f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
1837bd28ce00SJiri Slaby 	if (ret) {
18384291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
1839abf832bfSBenjamin Tissoires 		return ret;
1840bd28ce00SJiri Slaby 	}
1841bd28ce00SJiri Slaby 
18428025087aSFrank Praznik 	ret = sony_set_device_id(sc);
18438025087aSFrank Praznik 	if (ret < 0) {
18448025087aSFrank Praznik 		hid_err(hdev, "failed to allocate the device id\n");
18458025087aSFrank Praznik 		goto err_stop;
18468025087aSFrank Praznik 	}
18478025087aSFrank Praznik 
1848569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1849e534a935SBenjamin Tissoires 		/*
1850e534a935SBenjamin Tissoires 		 * The Sony Sixaxis does not handle HID Output Reports on the
1851e534a935SBenjamin Tissoires 		 * Interrupt EP like it could, so we need to force HID Output
1852e534a935SBenjamin Tissoires 		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
1853e534a935SBenjamin Tissoires 		 *
1854e534a935SBenjamin Tissoires 		 * There is also another issue about HID Output Reports via USB,
1855e534a935SBenjamin Tissoires 		 * the Sixaxis does not want the report_id as part of the data
1856e534a935SBenjamin Tissoires 		 * packet, so we have to discard buf[0] when sending the actual
1857e534a935SBenjamin Tissoires 		 * control message, even for numbered reports, humpf!
1858e534a935SBenjamin Tissoires 		 */
1859e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1860e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
1861816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
186246262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1863fee4e2d5SFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
18642078b9bbSFrank Praznik 		/*
18652078b9bbSFrank Praznik 		 * The Sixaxis wants output reports sent on the ctrl endpoint
18662078b9bbSFrank Praznik 		 * when connected via Bluetooth.
18672078b9bbSFrank Praznik 		 */
18682078b9bbSFrank Praznik 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
1869816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
187046262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
1871fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
187268330d83SFrank Praznik 		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
18732078b9bbSFrank Praznik 			/*
18742078b9bbSFrank Praznik 			 * The DualShock 4 wants output reports sent on the ctrl
18752078b9bbSFrank Praznik 			 * endpoint when connected via Bluetooth.
18762078b9bbSFrank Praznik 			 */
18772078b9bbSFrank Praznik 			hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
187868330d83SFrank Praznik 			ret = dualshock4_set_operational_bt(hdev);
187968330d83SFrank Praznik 			if (ret < 0) {
188068330d83SFrank Praznik 				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
188168330d83SFrank Praznik 				goto err_stop;
188268330d83SFrank Praznik 			}
188368330d83SFrank Praznik 		}
1884ad142b9eSFrank Praznik 		/*
1885ad142b9eSFrank Praznik 		 * The Dualshock 4 touchpad supports 2 touches and has a
1886e5606230SFrank Praznik 		 * resolution of 1920x940.
1887e5606230SFrank Praznik 		 */
1888e5606230SFrank Praznik 		ret = sony_register_touchpad(sc, 2, 1920, 940);
1889c4e1ddf2SFrank Praznik 		if (ret < 0)
1890c4e1ddf2SFrank Praznik 			goto err_stop;
1891c4e1ddf2SFrank Praznik 
189246262047SFrank Praznik 		sony_init_work(sc, dualshock4_state_worker);
18930bd88dd3SFrank Praznik 	} else {
18940bd88dd3SFrank Praznik 		ret = 0;
18950bd88dd3SFrank Praznik 	}
1896f9ce7c28SBastien Nocera 
18974dfdc464SJiri Kosina 	if (ret < 0)
1898bd28ce00SJiri Slaby 		goto err_stop;
1899bd28ce00SJiri Slaby 
1900d2d782fcSFrank Praznik 	ret = sony_check_add(sc);
1901d2d782fcSFrank Praznik 	if (ret < 0)
1902d2d782fcSFrank Praznik 		goto err_stop;
1903d2d782fcSFrank Praznik 
19040a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
1905fa57a810SFrank Praznik 		ret = sony_leds_init(sc);
19060a286ef2SSven Eckelmann 		if (ret < 0)
19070a286ef2SSven Eckelmann 			goto err_stop;
19080a286ef2SSven Eckelmann 	}
19090a286ef2SSven Eckelmann 
1910d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1911d902f472SFrank Praznik 		ret = sony_battery_probe(sc);
1912a08c22c0SSven Eckelmann 		if (ret < 0)
1913a08c22c0SSven Eckelmann 			goto err_stop;
1914a08c22c0SSven Eckelmann 
1915d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
1916d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
1917d902f472SFrank Praznik 		if (ret < 0) {
1918d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
1919d902f472SFrank Praznik 			goto err_stop;
1920d902f472SFrank Praznik 		}
1921d902f472SFrank Praznik 	}
1922d902f472SFrank Praznik 
1923c8de9dbbSFrank Praznik 	if (sc->quirks & SONY_FF_SUPPORT) {
1924fa57a810SFrank Praznik 		ret = sony_init_ff(sc);
1925d902f472SFrank Praznik 		if (ret < 0)
1926d902f472SFrank Praznik 			goto err_close;
19275f5750d2SFrank Praznik 	}
1928bd28ce00SJiri Slaby 
1929f425458eSH Hartley Sweeten 	return 0;
1930d902f472SFrank Praznik err_close:
1931d902f472SFrank Praznik 	hid_hw_close(hdev);
1932bd28ce00SJiri Slaby err_stop:
19330a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1934fa57a810SFrank Praznik 		sony_leds_remove(sc);
1935d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
1936d902f472SFrank Praznik 		sony_battery_remove(sc);
193746262047SFrank Praznik 	sony_cancel_work_sync(sc);
1938d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
19398025087aSFrank Praznik 	sony_release_device_id(sc);
1940bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
1941bd28ce00SJiri Slaby 	return ret;
1942bd28ce00SJiri Slaby }
1943bd28ce00SJiri Slaby 
1944bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev)
1945bd28ce00SJiri Slaby {
1946bd28ce00SJiri Slaby 	struct sony_sc *sc = hid_get_drvdata(hdev);
1947bd28ce00SJiri Slaby 
19480a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
1949fa57a810SFrank Praznik 		sony_leds_remove(sc);
1950bd28ce00SJiri Slaby 
1951d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
1952d902f472SFrank Praznik 		hid_hw_close(hdev);
1953d902f472SFrank Praznik 		sony_battery_remove(sc);
1954d902f472SFrank Praznik 	}
1955d902f472SFrank Praznik 
195646262047SFrank Praznik 	sony_cancel_work_sync(sc);
19579f323b68SSven Eckelmann 
1958d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
1959bd28ce00SJiri Slaby 
19608025087aSFrank Praznik 	sony_release_device_id(sc);
19618025087aSFrank Praznik 
1962bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
1963bd28ce00SJiri Slaby }
1964bd28ce00SJiri Slaby 
1965bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
1966bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1967bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
1968bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
1969bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
1970bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1971bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_BT },
1972bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
1973bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
1974bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
1975bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
1976bd28ce00SJiri Slaby 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
1977bd28ce00SJiri Slaby 	 * Logitech joystick from the device descriptor. */
1978bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
1979bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
1980bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
1981bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
1982bd28ce00SJiri Slaby 	/* PS3 BD Remote Control */
1983bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
1984bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
1985bd28ce00SJiri Slaby 	/* Logitech Harmony Adapter for PS3 */
1986bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
1987bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
19880bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
19890bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
19908ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
19910bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
19928ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
1993bd28ce00SJiri Slaby 	{ }
1994bd28ce00SJiri Slaby };
1995bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
1996bd28ce00SJiri Slaby 
1997bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
1998bd28ce00SJiri Slaby 	.name          = "sony",
1999bd28ce00SJiri Slaby 	.id_table      = sony_devices,
2000bd28ce00SJiri Slaby 	.input_mapping = sony_mapping,
2001bd28ce00SJiri Slaby 	.probe         = sony_probe,
2002bd28ce00SJiri Slaby 	.remove        = sony_remove,
2003bd28ce00SJiri Slaby 	.report_fixup  = sony_report_fixup,
2004bd28ce00SJiri Slaby 	.raw_event     = sony_raw_event
2005bd28ce00SJiri Slaby };
20068025087aSFrank Praznik 
20078025087aSFrank Praznik static int __init sony_init(void)
20088025087aSFrank Praznik {
20098025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20108025087aSFrank Praznik 
20118025087aSFrank Praznik 	return hid_register_driver(&sony_driver);
20128025087aSFrank Praznik }
20138025087aSFrank Praznik 
20148025087aSFrank Praznik static void __exit sony_exit(void)
20158025087aSFrank Praznik {
20168025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
20178025087aSFrank Praznik 
20188025087aSFrank Praznik 	ida_destroy(&sony_device_id_allocator);
20198025087aSFrank Praznik 	hid_unregister_driver(&sony_driver);
20208025087aSFrank Praznik }
20218025087aSFrank Praznik module_init(sony_init);
20228025087aSFrank Praznik module_exit(sony_exit);
2023bd28ce00SJiri Slaby 
2024bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
2025