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 20078328daSJiri Kosina /* NOTE: in order for the Sony PS3 BD Remote Control to be found by 21078328daSJiri Kosina * a Bluetooth host, the key combination Start+Enter has to be kept pressed 22078328daSJiri Kosina * for about 7 seconds with the Bluetooth Host Controller in discovering mode. 23078328daSJiri Kosina * 24078328daSJiri Kosina * There will be no PIN request from the device. 25078328daSJiri Kosina */ 26078328daSJiri Kosina 27bd28ce00SJiri Slaby #include <linux/device.h> 28bd28ce00SJiri Slaby #include <linux/hid.h> 29bd28ce00SJiri Slaby #include <linux/module.h> 305a0e3ad6STejun Heo #include <linux/slab.h> 31bd28ce00SJiri Slaby #include <linux/usb.h> 3240e32ee6SJiri Kosina #include <linux/leds.h> 33bd28ce00SJiri Slaby 34bd28ce00SJiri Slaby #include "hid-ids.h" 35bd28ce00SJiri Slaby 36f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 37f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 38f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 39f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 40f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 418ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 428ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 43cc6e0bbbSJiri Kosina 448ab1676bSFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) 4560781cf4SFrank Praznik 4660781cf4SFrank Praznik #define MAX_LEDS 4 470a286ef2SSven Eckelmann 4861ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 4961ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 5061ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 5161ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 5261ab44beSSimon Wood }; 5361ab44beSSimon Wood 54e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = { 55e57a67daSMauro Carvalho Chehab 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 56e57a67daSMauro Carvalho Chehab 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 57e57a67daSMauro Carvalho Chehab 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 58e57a67daSMauro Carvalho Chehab 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 59e57a67daSMauro Carvalho Chehab 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 60e57a67daSMauro Carvalho Chehab 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 61e57a67daSMauro Carvalho Chehab 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 62e57a67daSMauro Carvalho Chehab 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 63e57a67daSMauro Carvalho Chehab 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 64e57a67daSMauro Carvalho Chehab 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 65e57a67daSMauro Carvalho Chehab 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 66e57a67daSMauro Carvalho Chehab 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 67e57a67daSMauro Carvalho Chehab 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 68e57a67daSMauro Carvalho Chehab 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 69e57a67daSMauro Carvalho Chehab 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 70e57a67daSMauro Carvalho Chehab 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 71e57a67daSMauro Carvalho Chehab 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 72e57a67daSMauro Carvalho Chehab 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 73e57a67daSMauro Carvalho Chehab 0xb1, 0x02, 0xc0, 0xc0, 74e57a67daSMauro Carvalho Chehab }; 75e57a67daSMauro Carvalho Chehab 76*58d7027bSFrank Praznik /* The default descriptor doesn't provide mapping for the accelerometers 77*58d7027bSFrank Praznik * or orientation sensors. This fixed descriptor maps the accelerometers 78*58d7027bSFrank Praznik * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors 79*58d7027bSFrank Praznik * to usage values 0x43, 0x44 and 0x45. 80*58d7027bSFrank Praznik */ 81ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = { 82*58d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 83*58d7027bSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 84*58d7027bSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 85*58d7027bSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 86*58d7027bSFrank Praznik 0x09, 0x30, /* Usage (X), */ 87*58d7027bSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 88*58d7027bSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 89*58d7027bSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 90*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 91*58d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 92*58d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 93*58d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 94*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 95*58d7027bSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 96*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 97*58d7027bSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 98*58d7027bSFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 99*58d7027bSFrank Praznik 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 100*58d7027bSFrank Praznik 0x65, 0x14, /* Unit (Degrees), */ 101*58d7027bSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 102*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 103*58d7027bSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 104*58d7027bSFrank Praznik 0x65, 0x00, /* Unit, */ 105*58d7027bSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 106*58d7027bSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 107*58d7027bSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 108*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 109*58d7027bSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 110*58d7027bSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 111*58d7027bSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 112*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 113*58d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 114*58d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 115*58d7027bSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 116*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 117*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 118*58d7027bSFrank Praznik 0x25, 0x7F, /* Logical Maximum (127), */ 119*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 120*58d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 121*58d7027bSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 122*58d7027bSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 123*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 124*58d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 125*58d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 126*58d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 127*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 128*58d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 129*58d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 130*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 131*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 132*58d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 133*58d7027bSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 134*58d7027bSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 135*58d7027bSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 136*58d7027bSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 137*58d7027bSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 138*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 139*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 140*58d7027bSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 141*58d7027bSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 142*58d7027bSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 143*58d7027bSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 144*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 145*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 146*58d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 147*58d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 148*58d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 149*58d7027bSFrank Praznik 0x25, 0xFF, /* Logical Maximum (255), */ 150*58d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 151*58d7027bSFrank Praznik 0x95, 0x27, /* Report Count (39), */ 152*58d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 153*58d7027bSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 154*58d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 155*58d7027bSFrank Praznik 0x95, 0x1F, /* Report Count (31), */ 156*58d7027bSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 157*58d7027bSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 158*58d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 159*58d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 160*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 161*58d7027bSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 162*58d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 163*58d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 164*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 165*58d7027bSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 166*58d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 167*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 168*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 169*58d7027bSFrank Praznik 0x85, 0x10, /* Report ID (16), */ 170*58d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 171*58d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 172*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 173*58d7027bSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 174*58d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 175*58d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 176*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 177*58d7027bSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 178*58d7027bSFrank Praznik 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ 179*58d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 180*58d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 181*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 182*58d7027bSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 183*58d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 184*58d7027bSFrank Praznik 0x95, 0x16, /* Report Count (22), */ 185*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 186*58d7027bSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 187*58d7027bSFrank Praznik 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ 188*58d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 189*58d7027bSFrank Praznik 0x95, 0x10, /* Report Count (16), */ 190*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 191*58d7027bSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 192*58d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 193*58d7027bSFrank Praznik 0x95, 0x2C, /* Report Count (44), */ 194*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 195*58d7027bSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 196*58d7027bSFrank Praznik 0x85, 0x80, /* Report ID (128), */ 197*58d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 198*58d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 199*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 200*58d7027bSFrank Praznik 0x85, 0x81, /* Report ID (129), */ 201*58d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 202*58d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 203*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 204*58d7027bSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 205*58d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 206*58d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 207*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 208*58d7027bSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 209*58d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 210*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 211*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 212*58d7027bSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 213*58d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 214*58d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 215*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 216*58d7027bSFrank Praznik 0x85, 0x85, /* Report ID (133), */ 217*58d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 218*58d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 219*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 220*58d7027bSFrank Praznik 0x85, 0x86, /* Report ID (134), */ 221*58d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 222*58d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 223*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 224*58d7027bSFrank Praznik 0x85, 0x87, /* Report ID (135), */ 225*58d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 226*58d7027bSFrank Praznik 0x95, 0x23, /* Report Count (35), */ 227*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 228*58d7027bSFrank Praznik 0x85, 0x88, /* Report ID (136), */ 229*58d7027bSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 230*58d7027bSFrank Praznik 0x95, 0x22, /* Report Count (34), */ 231*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 232*58d7027bSFrank Praznik 0x85, 0x89, /* Report ID (137), */ 233*58d7027bSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 234*58d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 235*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 236*58d7027bSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 237*58d7027bSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 238*58d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 239*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 240*58d7027bSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 241*58d7027bSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 242*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 243*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 244*58d7027bSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 245*58d7027bSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 246*58d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 247*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 248*58d7027bSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 249*58d7027bSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 250*58d7027bSFrank Praznik 0x95, 0x0C, /* Report Count (12), */ 251*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 252*58d7027bSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 253*58d7027bSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 254*58d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 255*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 256*58d7027bSFrank Praznik 0x85, 0xA1, /* Report ID (161), */ 257*58d7027bSFrank Praznik 0x09, 0x41, /* Usage (41h), */ 258*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 259*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 260*58d7027bSFrank Praznik 0x85, 0xA2, /* Report ID (162), */ 261*58d7027bSFrank Praznik 0x09, 0x42, /* Usage (42h), */ 262*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 263*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 264*58d7027bSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 265*58d7027bSFrank Praznik 0x09, 0x43, /* Usage (43h), */ 266*58d7027bSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 267*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 268*58d7027bSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 269*58d7027bSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 270*58d7027bSFrank Praznik 0x95, 0x0D, /* Report Count (13), */ 271*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 272*58d7027bSFrank Praznik 0x85, 0xA5, /* Report ID (165), */ 273*58d7027bSFrank Praznik 0x09, 0x45, /* Usage (45h), */ 274*58d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 275*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 276*58d7027bSFrank Praznik 0x85, 0xA6, /* Report ID (166), */ 277*58d7027bSFrank Praznik 0x09, 0x46, /* Usage (46h), */ 278*58d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 279*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 280*58d7027bSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 281*58d7027bSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 282*58d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 283*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 284*58d7027bSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 285*58d7027bSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 286*58d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 287*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 288*58d7027bSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 289*58d7027bSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 290*58d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 291*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 292*58d7027bSFrank Praznik 0x85, 0xA7, /* Report ID (167), */ 293*58d7027bSFrank Praznik 0x09, 0x4A, /* Usage (4Ah), */ 294*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 295*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 296*58d7027bSFrank Praznik 0x85, 0xA8, /* Report ID (168), */ 297*58d7027bSFrank Praznik 0x09, 0x4B, /* Usage (4Bh), */ 298*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 299*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 300*58d7027bSFrank Praznik 0x85, 0xA9, /* Report ID (169), */ 301*58d7027bSFrank Praznik 0x09, 0x4C, /* Usage (4Ch), */ 302*58d7027bSFrank Praznik 0x95, 0x08, /* Report Count (8), */ 303*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 304*58d7027bSFrank Praznik 0x85, 0xAA, /* Report ID (170), */ 305*58d7027bSFrank Praznik 0x09, 0x4E, /* Usage (4Eh), */ 306*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 307*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 308*58d7027bSFrank Praznik 0x85, 0xAB, /* Report ID (171), */ 309*58d7027bSFrank Praznik 0x09, 0x4F, /* Usage (4Fh), */ 310*58d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 311*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 312*58d7027bSFrank Praznik 0x85, 0xAC, /* Report ID (172), */ 313*58d7027bSFrank Praznik 0x09, 0x50, /* Usage (50h), */ 314*58d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 315*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 316*58d7027bSFrank Praznik 0x85, 0xAD, /* Report ID (173), */ 317*58d7027bSFrank Praznik 0x09, 0x51, /* Usage (51h), */ 318*58d7027bSFrank Praznik 0x95, 0x0B, /* Report Count (11), */ 319*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 320*58d7027bSFrank Praznik 0x85, 0xAE, /* Report ID (174), */ 321*58d7027bSFrank Praznik 0x09, 0x52, /* Usage (52h), */ 322*58d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 323*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 324*58d7027bSFrank Praznik 0x85, 0xAF, /* Report ID (175), */ 325*58d7027bSFrank Praznik 0x09, 0x53, /* Usage (53h), */ 326*58d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 327*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 328*58d7027bSFrank Praznik 0x85, 0xB0, /* Report ID (176), */ 329*58d7027bSFrank Praznik 0x09, 0x54, /* Usage (54h), */ 330*58d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 331*58d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 332*58d7027bSFrank Praznik 0xC0 /* End Collection */ 333ed19d8cfSFrank Praznik }; 334ed19d8cfSFrank Praznik 335078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 336078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 337078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 338078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 339078328daSJiri Kosina 340078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 341078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 342078328daSJiri Kosina 343078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 344078328daSJiri Kosina * number but it's not needed for correct operation */ 345078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 346078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 347078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 348078328daSJiri Kosina 349078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 350078328daSJiri Kosina * buttons multiple keypresses are allowed */ 351078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 352078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 353078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 354078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 355078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 356078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 357078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 358078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 359078328daSJiri Kosina 360078328daSJiri Kosina 0xC0, /* MEndCollection */ 361078328daSJiri Kosina 362078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 363078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 364078328daSJiri Kosina 365078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 366078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 367078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 368078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 369078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 370078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 371078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 372078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 373078328daSJiri Kosina 0x80, /* MInput */ 374078328daSJiri Kosina 375078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 376078328daSJiri Kosina * 0xff and 11th is for press indication */ 377078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 378078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 379078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 380078328daSJiri Kosina 381078328daSJiri Kosina /* 12th byte is for battery strength */ 382078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 383078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 384078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 385078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 386078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 387078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 388078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 389078328daSJiri Kosina 390078328daSJiri Kosina 0xC0, /* MEndCollection */ 391078328daSJiri Kosina 392078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 393078328daSJiri Kosina }; 394078328daSJiri Kosina 395078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 396078328daSJiri Kosina [0x01] = KEY_SELECT, 397078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 398078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 399078328daSJiri Kosina [0x04] = BTN_START, 400078328daSJiri Kosina [0x05] = KEY_UP, 401078328daSJiri Kosina [0x06] = KEY_RIGHT, 402078328daSJiri Kosina [0x07] = KEY_DOWN, 403078328daSJiri Kosina [0x08] = KEY_LEFT, 404078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 405078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 406078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 407078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 408078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 409078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 410078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 411078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 412078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 413078328daSJiri Kosina [0x14] = KEY_ENTER, 414078328daSJiri Kosina }; 415078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 416078328daSJiri Kosina [0x00] = KEY_1, 417078328daSJiri Kosina [0x01] = KEY_2, 418078328daSJiri Kosina [0x02] = KEY_3, 419078328daSJiri Kosina [0x03] = KEY_4, 420078328daSJiri Kosina [0x04] = KEY_5, 421078328daSJiri Kosina [0x05] = KEY_6, 422078328daSJiri Kosina [0x06] = KEY_7, 423078328daSJiri Kosina [0x07] = KEY_8, 424078328daSJiri Kosina [0x08] = KEY_9, 425078328daSJiri Kosina [0x09] = KEY_0, 426078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 427078328daSJiri Kosina [0x0f] = KEY_CLEAR, 428078328daSJiri Kosina [0x16] = KEY_EJECTCD, 429078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 430078328daSJiri Kosina [0x28] = KEY_TIME, 431078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 432078328daSJiri Kosina [0x31] = KEY_NEXT, 433078328daSJiri Kosina [0x32] = KEY_PLAY, 434078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 435078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 436078328daSJiri Kosina [0x38] = KEY_STOP, 437078328daSJiri Kosina [0x39] = KEY_PAUSE, 438078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 439078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 440078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 441078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 442078328daSJiri Kosina [0x64] = KEY_AUDIO, 443078328daSJiri Kosina [0x65] = KEY_ANGLE, 444078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 445078328daSJiri Kosina [0x80] = KEY_BLUE, 446078328daSJiri Kosina [0x81] = KEY_RED, 447078328daSJiri Kosina [0x82] = KEY_GREEN, 448078328daSJiri Kosina [0x83] = KEY_YELLOW, 449078328daSJiri Kosina }; 450078328daSJiri Kosina 451f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 452f04d5140SColin Leitner /* The controller has 4 remote buzzers, each with one LED and 5 453f04d5140SColin Leitner * buttons. 454f04d5140SColin Leitner * 455f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 456f04d5140SColin Leitner * 457f04d5140SColin Leitner * Key Offset 458f04d5140SColin Leitner * ------------------- 459f04d5140SColin Leitner * Buzz 1 460f04d5140SColin Leitner * Blue 5 461f04d5140SColin Leitner * Orange 4 462f04d5140SColin Leitner * Green 3 463f04d5140SColin Leitner * Yellow 2 464f04d5140SColin Leitner * 465f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 466f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 467f04d5140SColin Leitner */ 468f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 469f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 470f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 471f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 472f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 473f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 474f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 475f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 476f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 477f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 478f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 479f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 480f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 481f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 482f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 483f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 484f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 485f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 486f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 487f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 488f04d5140SColin Leitner }; 489f04d5140SColin Leitner 490cc6e0bbbSJiri Kosina struct sony_sc { 4910a286ef2SSven Eckelmann struct hid_device *hdev; 49260781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 493c4e1ddf2SFrank Praznik struct hid_report *output_report; 494cc6e0bbbSJiri Kosina unsigned long quirks; 4950a286ef2SSven Eckelmann struct work_struct state_worker; 496f04d5140SColin Leitner 4979f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 4989f323b68SSven Eckelmann __u8 left; 4999f323b68SSven Eckelmann __u8 right; 5009f323b68SSven Eckelmann #endif 5019f323b68SSven Eckelmann 50260781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 50360781cf4SFrank Praznik __u8 led_count; 504cc6e0bbbSJiri Kosina }; 505cc6e0bbbSJiri Kosina 506078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 507078328daSJiri Kosina unsigned int *rsize) 508078328daSJiri Kosina { 509078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 510078328daSJiri Kosina return ps3remote_rdesc; 511078328daSJiri Kosina } 512078328daSJiri Kosina 513078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 514078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 515078328daSJiri Kosina unsigned long **bit, int *max) 516078328daSJiri Kosina { 517078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 518078328daSJiri Kosina 519078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 520078328daSJiri Kosina return -1; 521078328daSJiri Kosina 522078328daSJiri Kosina switch (usage->collection_index) { 523078328daSJiri Kosina case 1: 524078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 525078328daSJiri Kosina return -1; 526078328daSJiri Kosina 527078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 528078328daSJiri Kosina if (!key) 529078328daSJiri Kosina return -1; 530078328daSJiri Kosina break; 531078328daSJiri Kosina case 2: 532078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 533078328daSJiri Kosina return -1; 534078328daSJiri Kosina 535078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 536078328daSJiri Kosina if (!key) 537078328daSJiri Kosina return -1; 538078328daSJiri Kosina break; 539078328daSJiri Kosina default: 540078328daSJiri Kosina return -1; 541078328daSJiri Kosina } 542078328daSJiri Kosina 543078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 544078328daSJiri Kosina return 1; 545078328daSJiri Kosina } 546078328daSJiri Kosina 547078328daSJiri Kosina 548cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 54973e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 55073e4008dSNikolai Kondrashov unsigned int *rsize) 551cc6e0bbbSJiri Kosina { 552cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 553cc6e0bbbSJiri Kosina 55499d24902SFernando Luis Vázquez Cao /* 55599d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 55699d24902SFernando Luis Vázquez Cao * a constant non-data variable. 55799d24902SFernando Luis Vázquez Cao */ 55899d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 55999d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 56099d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 56199d24902SFernando Luis Vázquez Cao /* usage: mouse */ 56299d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 56399d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 56499d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 565a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 56699d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 567cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 568cc6e0bbbSJiri Kosina } 56961ab44beSSimon Wood 570ed19d8cfSFrank Praznik /* 571ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 572ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 573ed19d8cfSFrank Praznik * modified one. 574ed19d8cfSFrank Praznik */ 575ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 576ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 577ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 578ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 579ed19d8cfSFrank Praznik } 580ed19d8cfSFrank Praznik 58161ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 58261ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 58361ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 58461ab44beSSimon Wood rdesc[83] == 0x75) { 58561ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 58661ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 58761ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 588e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 589e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 590e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 591e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 592e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 593e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 59461ab44beSSimon Wood } 595078328daSJiri Kosina 596078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 597078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 598078328daSJiri Kosina 59973e4008dSNikolai Kondrashov return rdesc; 600cc6e0bbbSJiri Kosina } 601cc6e0bbbSJiri Kosina 602c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 603c9e4d877SSimon Wood __u8 *rd, int size) 604c9e4d877SSimon Wood { 605c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 606c9e4d877SSimon Wood 607c9e4d877SSimon Wood /* Sixaxis HID report has acclerometers/gyro with MSByte first, this 608c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 609c9e4d877SSimon Wood */ 610c9e4d877SSimon Wood if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) && 611c9e4d877SSimon Wood rd[0] == 0x01 && size == 49) { 612c9e4d877SSimon Wood swap(rd[41], rd[42]); 613c9e4d877SSimon Wood swap(rd[43], rd[44]); 614c9e4d877SSimon Wood swap(rd[45], rd[46]); 615c9e4d877SSimon Wood swap(rd[47], rd[48]); 616c9e4d877SSimon Wood } 617c9e4d877SSimon Wood 618c9e4d877SSimon Wood return 0; 619c9e4d877SSimon Wood } 620c9e4d877SSimon Wood 621f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 622f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 623f04d5140SColin Leitner unsigned long **bit, int *max) 624f04d5140SColin Leitner { 625f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 626f04d5140SColin Leitner 627f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 628f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 629f04d5140SColin Leitner 630f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 631f04d5140SColin Leitner return -1; 632f04d5140SColin Leitner 633f04d5140SColin Leitner switch (usage->collection_index) { 634f04d5140SColin Leitner case 1: 635f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 636f04d5140SColin Leitner return -1; 637f04d5140SColin Leitner 638f04d5140SColin Leitner key = buzz_keymap[key]; 639f04d5140SColin Leitner if (!key) 640f04d5140SColin Leitner return -1; 641f04d5140SColin Leitner break; 642f04d5140SColin Leitner default: 643f04d5140SColin Leitner return -1; 644f04d5140SColin Leitner } 645f04d5140SColin Leitner 646f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 647f04d5140SColin Leitner return 1; 648f04d5140SColin Leitner } 649f04d5140SColin Leitner 650078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 651078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 652078328daSJiri Kosina 6536f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 6546f498018SBenjamin Tissoires return 0; 655f04d5140SColin Leitner } 656f04d5140SColin Leitner 6575710fabfSAntonio Ospite /* 6585710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 6595710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 6605710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 6615710fabfSAntonio Ospite * 6625710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 6635710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 6645710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 6655710fabfSAntonio Ospite * reports, humpf! 6665710fabfSAntonio Ospite */ 667569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 668569b10a5SAntonio Ospite size_t count, unsigned char report_type) 669569b10a5SAntonio Ospite { 670569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 671569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 672569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 673569b10a5SAntonio Ospite int report_id = buf[0]; 674569b10a5SAntonio Ospite int ret; 675569b10a5SAntonio Ospite 6765710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 6775710fabfSAntonio Ospite /* Don't send the Report ID */ 6785710fabfSAntonio Ospite buf++; 6795710fabfSAntonio Ospite count--; 6805710fabfSAntonio Ospite } 6815710fabfSAntonio Ospite 682569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 683569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 684569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 685569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 686569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 687569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 688569b10a5SAntonio Ospite 6895710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 6905710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 6915710fabfSAntonio Ospite ret++; 6925710fabfSAntonio Ospite 693569b10a5SAntonio Ospite return ret; 694569b10a5SAntonio Ospite } 695569b10a5SAntonio Ospite 696bd28ce00SJiri Slaby /* 697bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 698bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 699bd28ce00SJiri Slaby * events. 700bd28ce00SJiri Slaby */ 701816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 702bd28ce00SJiri Slaby { 703bd28ce00SJiri Slaby int ret; 704bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 705bd28ce00SJiri Slaby 706bd28ce00SJiri Slaby if (!buf) 707bd28ce00SJiri Slaby return -ENOMEM; 708bd28ce00SJiri Slaby 709f204828aSBenjamin Tissoires ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT); 710f204828aSBenjamin Tissoires 711bd28ce00SJiri Slaby if (ret < 0) 7124291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 713bd28ce00SJiri Slaby 714bd28ce00SJiri Slaby kfree(buf); 715bd28ce00SJiri Slaby 716bd28ce00SJiri Slaby return ret; 717bd28ce00SJiri Slaby } 718bd28ce00SJiri Slaby 719816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 720f9ce7c28SBastien Nocera { 721fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 722f9ce7c28SBastien Nocera return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 723f9ce7c28SBastien Nocera } 724f9ce7c28SBastien Nocera 72560781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 726f04d5140SColin Leitner { 727f04d5140SColin Leitner struct list_head *report_list = 728f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 729f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 730f04d5140SColin Leitner struct hid_report, list); 731f04d5140SColin Leitner __s32 *value = report->field[0]->value; 732f04d5140SColin Leitner 733f04d5140SColin Leitner value[0] = 0x00; 73460781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 73560781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 73660781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 73760781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 738f04d5140SColin Leitner value[5] = 0x00; 739f04d5140SColin Leitner value[6] = 0x00; 740f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 741f04d5140SColin Leitner } 742f04d5140SColin Leitner 74360781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) 7440a286ef2SSven Eckelmann { 7450a286ef2SSven Eckelmann struct sony_sc *drv_data = hid_get_drvdata(hdev); 74660781cf4SFrank Praznik int n; 7470a286ef2SSven Eckelmann 74860781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 74960781cf4SFrank Praznik 75060781cf4SFrank Praznik if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { 7510a286ef2SSven Eckelmann buzz_set_leds(hdev, leds); 75260781cf4SFrank Praznik } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) || 7538ab1676bSFrank Praznik (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) { 75460781cf4SFrank Praznik for (n = 0; n < count; n++) 75560781cf4SFrank Praznik drv_data->led_state[n] = leds[n]; 7560a286ef2SSven Eckelmann schedule_work(&drv_data->state_worker); 7570a286ef2SSven Eckelmann } 7580a286ef2SSven Eckelmann } 7590a286ef2SSven Eckelmann 760c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 761f04d5140SColin Leitner enum led_brightness value) 762f04d5140SColin Leitner { 763f04d5140SColin Leitner struct device *dev = led->dev->parent; 764f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 765f04d5140SColin Leitner struct sony_sc *drv_data; 766f04d5140SColin Leitner 767f04d5140SColin Leitner int n; 768f04d5140SColin Leitner 769f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 7702251b85fSSven Eckelmann if (!drv_data) { 771f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 772f04d5140SColin Leitner return; 773f04d5140SColin Leitner } 774f04d5140SColin Leitner 77560781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 7762251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 77760781cf4SFrank Praznik if (value != drv_data->led_state[n]) { 77860781cf4SFrank Praznik drv_data->led_state[n] = value; 77960781cf4SFrank Praznik sony_set_leds(hdev, drv_data->led_state, drv_data->led_count); 780f04d5140SColin Leitner } 781f04d5140SColin Leitner break; 782f04d5140SColin Leitner } 783f04d5140SColin Leitner } 784f04d5140SColin Leitner } 785f04d5140SColin Leitner 786c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 787f04d5140SColin Leitner { 788f04d5140SColin Leitner struct device *dev = led->dev->parent; 789f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 790f04d5140SColin Leitner struct sony_sc *drv_data; 791f04d5140SColin Leitner 792f04d5140SColin Leitner int n; 793f04d5140SColin Leitner int on = 0; 794f04d5140SColin Leitner 795f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 7962251b85fSSven Eckelmann if (!drv_data) { 797f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 798f04d5140SColin Leitner return LED_OFF; 799f04d5140SColin Leitner } 800f04d5140SColin Leitner 80160781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 8022251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 80360781cf4SFrank Praznik on = !!(drv_data->led_state[n]); 804f04d5140SColin Leitner break; 805f04d5140SColin Leitner } 806f04d5140SColin Leitner } 807f04d5140SColin Leitner 808f04d5140SColin Leitner return on ? LED_FULL : LED_OFF; 809f04d5140SColin Leitner } 810f04d5140SColin Leitner 8110a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev) 8120a286ef2SSven Eckelmann { 8130a286ef2SSven Eckelmann struct sony_sc *drv_data; 8140a286ef2SSven Eckelmann struct led_classdev *led; 8150a286ef2SSven Eckelmann int n; 8160a286ef2SSven Eckelmann 8170a286ef2SSven Eckelmann drv_data = hid_get_drvdata(hdev); 8180a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 8190a286ef2SSven Eckelmann 82060781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 8210a286ef2SSven Eckelmann led = drv_data->leds[n]; 8220a286ef2SSven Eckelmann drv_data->leds[n] = NULL; 8230a286ef2SSven Eckelmann if (!led) 8240a286ef2SSven Eckelmann continue; 8250a286ef2SSven Eckelmann led_classdev_unregister(led); 8260a286ef2SSven Eckelmann kfree(led); 8270a286ef2SSven Eckelmann } 82860781cf4SFrank Praznik 82960781cf4SFrank Praznik drv_data->led_count = 0; 8300a286ef2SSven Eckelmann } 8310a286ef2SSven Eckelmann 832c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev) 833f04d5140SColin Leitner { 834f04d5140SColin Leitner struct sony_sc *drv_data; 83540e32ee6SJiri Kosina int n, ret = 0; 83660781cf4SFrank Praznik int max_brightness; 83740e32ee6SJiri Kosina struct led_classdev *led; 83840e32ee6SJiri Kosina size_t name_sz; 83940e32ee6SJiri Kosina char *name; 8400a286ef2SSven Eckelmann size_t name_len; 8410a286ef2SSven Eckelmann const char *name_fmt; 84260781cf4SFrank Praznik static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 }; 843f04d5140SColin Leitner 844f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 8450a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 846f04d5140SColin Leitner 8470a286ef2SSven Eckelmann if (drv_data->quirks & BUZZ_CONTROLLER) { 8480a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 8490a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 8509446edb9SKees Cook /* Validate expected report characteristics. */ 8519446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 8529446edb9SKees Cook return -ENODEV; 8530a286ef2SSven Eckelmann } else { 8540a286ef2SSven Eckelmann name_len = strlen("::sony#"); 8550a286ef2SSven Eckelmann name_fmt = "%s::sony%d"; 8560a286ef2SSven Eckelmann } 8579446edb9SKees Cook 8588ab1676bSFrank Praznik if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) { 85960781cf4SFrank Praznik drv_data->led_count = 3; 86060781cf4SFrank Praznik max_brightness = 255; 86160781cf4SFrank Praznik } else { 86260781cf4SFrank Praznik drv_data->led_count = 4; 86360781cf4SFrank Praznik max_brightness = 1; 86460781cf4SFrank Praznik } 86560781cf4SFrank Praznik 866f04d5140SColin Leitner /* Clear LEDs as we have no way of reading their initial state. This is 867f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 868f04d5140SColin Leitner * LEDs to on */ 86960781cf4SFrank Praznik sony_set_leds(hdev, initial_values, drv_data->led_count); 870f04d5140SColin Leitner 8710a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 872f04d5140SColin Leitner 87360781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 874f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 875f04d5140SColin Leitner if (!led) { 876f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 8778cd5fcdaSJulia Lawall ret = -ENOMEM; 878f04d5140SColin Leitner goto error_leds; 879f04d5140SColin Leitner } 880f04d5140SColin Leitner 881f04d5140SColin Leitner name = (void *)(&led[1]); 8820a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 883f04d5140SColin Leitner led->name = name; 884f04d5140SColin Leitner led->brightness = 0; 88560781cf4SFrank Praznik led->max_brightness = max_brightness; 886c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 887c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 888f04d5140SColin Leitner 8898cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 8908cd5fcdaSJulia Lawall if (ret) { 891f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 892f04d5140SColin Leitner kfree(led); 893f04d5140SColin Leitner goto error_leds; 894f04d5140SColin Leitner } 895f04d5140SColin Leitner 8962251b85fSSven Eckelmann drv_data->leds[n] = led; 897f04d5140SColin Leitner } 898f04d5140SColin Leitner 899f04d5140SColin Leitner return ret; 900f04d5140SColin Leitner 901f04d5140SColin Leitner error_leds: 9020a286ef2SSven Eckelmann sony_leds_remove(hdev); 903f04d5140SColin Leitner 904f04d5140SColin Leitner return ret; 905f04d5140SColin Leitner } 906f04d5140SColin Leitner 907cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 908a08c22c0SSven Eckelmann { 90992b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 910a08c22c0SSven Eckelmann unsigned char buf[] = { 911a08c22c0SSven Eckelmann 0x01, 912a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 9130a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 914a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 915a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 916a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 917a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 918a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 919a08c22c0SSven Eckelmann }; 9209f323b68SSven Eckelmann 9210a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 9220bd88dd3SFrank Praznik buf[3] = sc->right ? 1 : 0; 9239f323b68SSven Eckelmann buf[5] = sc->left; 9240a286ef2SSven Eckelmann #endif 9250a286ef2SSven Eckelmann 92660781cf4SFrank Praznik buf[10] |= sc->led_state[0] << 1; 92760781cf4SFrank Praznik buf[10] |= sc->led_state[1] << 2; 92860781cf4SFrank Praznik buf[10] |= sc->led_state[2] << 3; 92960781cf4SFrank Praznik buf[10] |= sc->led_state[3] << 4; 9309f323b68SSven Eckelmann 9319f323b68SSven Eckelmann sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf), 9329f323b68SSven Eckelmann HID_OUTPUT_REPORT); 9339f323b68SSven Eckelmann } 9349f323b68SSven Eckelmann 9350bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 9360bd88dd3SFrank Praznik { 9370bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 9380da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 939c4e1ddf2SFrank Praznik struct hid_report *report = sc->output_report; 940c4e1ddf2SFrank Praznik __s32 *value = report->field[0]->value; 9410da8ea65SFrank Praznik 9420da8ea65SFrank Praznik value[0] = 0x03; 9430bd88dd3SFrank Praznik 9440bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 9450da8ea65SFrank Praznik value[3] = sc->right; 9460da8ea65SFrank Praznik value[4] = sc->left; 9470bd88dd3SFrank Praznik #endif 9480bd88dd3SFrank Praznik 9490da8ea65SFrank Praznik value[5] = sc->led_state[0]; 9500da8ea65SFrank Praznik value[6] = sc->led_state[1]; 9510da8ea65SFrank Praznik value[7] = sc->led_state[2]; 95260781cf4SFrank Praznik 9530da8ea65SFrank Praznik hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 9540bd88dd3SFrank Praznik } 9550bd88dd3SFrank Praznik 9560a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 9579f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 9589f323b68SSven Eckelmann struct ff_effect *effect) 9599f323b68SSven Eckelmann { 960a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 9619f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 962a08c22c0SSven Eckelmann 963a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 964a08c22c0SSven Eckelmann return 0; 965a08c22c0SSven Eckelmann 9669f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 9670bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 968a08c22c0SSven Eckelmann 96992b5c411SSven Eckelmann schedule_work(&sc->state_worker); 9709f323b68SSven Eckelmann return 0; 971a08c22c0SSven Eckelmann } 972a08c22c0SSven Eckelmann 973a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 974a08c22c0SSven Eckelmann { 975a08c22c0SSven Eckelmann struct hid_input *hidinput = list_entry(hdev->inputs.next, 976a08c22c0SSven Eckelmann struct hid_input, list); 977a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 978a08c22c0SSven Eckelmann 979a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 980a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 981a08c22c0SSven Eckelmann } 982a08c22c0SSven Eckelmann 9839f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 9849f323b68SSven Eckelmann { 9859f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hdev); 9869f323b68SSven Eckelmann 98792b5c411SSven Eckelmann cancel_work_sync(&sc->state_worker); 9889f323b68SSven Eckelmann } 9899f323b68SSven Eckelmann 990a08c22c0SSven Eckelmann #else 991a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 992a08c22c0SSven Eckelmann { 993a08c22c0SSven Eckelmann return 0; 994a08c22c0SSven Eckelmann } 9959f323b68SSven Eckelmann 9969f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 9979f323b68SSven Eckelmann { 9989f323b68SSven Eckelmann } 999a08c22c0SSven Eckelmann #endif 1000a08c22c0SSven Eckelmann 1001c4e1ddf2SFrank Praznik static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) 1002c4e1ddf2SFrank Praznik { 1003c4e1ddf2SFrank Praznik struct list_head *head, *list; 1004c4e1ddf2SFrank Praznik struct hid_report *report; 1005c4e1ddf2SFrank Praznik struct hid_device *hdev = sc->hdev; 1006c4e1ddf2SFrank Praznik 1007c4e1ddf2SFrank Praznik list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1008c4e1ddf2SFrank Praznik 1009c4e1ddf2SFrank Praznik list_for_each(head, list) { 1010c4e1ddf2SFrank Praznik report = list_entry(head, struct hid_report, list); 1011c4e1ddf2SFrank Praznik 1012c4e1ddf2SFrank Praznik if (report->id == req_id) { 1013c4e1ddf2SFrank Praznik if (report->size < req_size) { 1014c4e1ddf2SFrank Praznik hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n", 1015c4e1ddf2SFrank Praznik req_id, report->size, req_size); 1016c4e1ddf2SFrank Praznik return -EINVAL; 1017c4e1ddf2SFrank Praznik } 1018c4e1ddf2SFrank Praznik sc->output_report = report; 1019c4e1ddf2SFrank Praznik return 0; 1020c4e1ddf2SFrank Praznik } 1021c4e1ddf2SFrank Praznik } 1022c4e1ddf2SFrank Praznik 1023c4e1ddf2SFrank Praznik hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id); 1024c4e1ddf2SFrank Praznik 1025c4e1ddf2SFrank Praznik return -EINVAL; 1026c4e1ddf2SFrank Praznik } 1027c4e1ddf2SFrank Praznik 1028bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1029bd28ce00SJiri Slaby { 1030bd28ce00SJiri Slaby int ret; 1031cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1032cc6e0bbbSJiri Kosina struct sony_sc *sc; 1033f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1034cc6e0bbbSJiri Kosina 1035abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1036cc6e0bbbSJiri Kosina if (sc == NULL) { 10374291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1038cc6e0bbbSJiri Kosina return -ENOMEM; 1039cc6e0bbbSJiri Kosina } 1040cc6e0bbbSJiri Kosina 1041cc6e0bbbSJiri Kosina sc->quirks = quirks; 1042cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 10430a286ef2SSven Eckelmann sc->hdev = hdev; 1044bd28ce00SJiri Slaby 1045bd28ce00SJiri Slaby ret = hid_parse(hdev); 1046bd28ce00SJiri Slaby if (ret) { 10474291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1048abf832bfSBenjamin Tissoires return ret; 1049bd28ce00SJiri Slaby } 1050bd28ce00SJiri Slaby 1051f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1052f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1053f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 1054f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1055f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 1056f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1057f04d5140SColin Leitner 1058f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1059bd28ce00SJiri Slaby if (ret) { 10604291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1061abf832bfSBenjamin Tissoires return ret; 1062bd28ce00SJiri Slaby } 1063bd28ce00SJiri Slaby 1064569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1065569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 1066816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 1067cad665a2SFrank Praznik INIT_WORK(&sc->state_worker, sixaxis_state_worker); 1068569b10a5SAntonio Ospite } 1069816651a7SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 1070816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 10718ab1676bSFrank Praznik else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1072c4e1ddf2SFrank Praznik /* Report 5 (31 bytes) is used to send data to the controller via USB */ 1073c4e1ddf2SFrank Praznik ret = sony_set_output_report(sc, 0x05, 248); 1074c4e1ddf2SFrank Praznik if (ret < 0) 1075c4e1ddf2SFrank Praznik goto err_stop; 1076c4e1ddf2SFrank Praznik 10770bd88dd3SFrank Praznik INIT_WORK(&sc->state_worker, dualshock4_state_worker); 10780bd88dd3SFrank Praznik } else { 10790bd88dd3SFrank Praznik ret = 0; 10800bd88dd3SFrank Praznik } 1081f9ce7c28SBastien Nocera 10824dfdc464SJiri Kosina if (ret < 0) 1083bd28ce00SJiri Slaby goto err_stop; 1084bd28ce00SJiri Slaby 10850a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 10860a286ef2SSven Eckelmann ret = sony_leds_init(hdev); 10870a286ef2SSven Eckelmann if (ret < 0) 10880a286ef2SSven Eckelmann goto err_stop; 10890a286ef2SSven Eckelmann } 10900a286ef2SSven Eckelmann 1091a08c22c0SSven Eckelmann ret = sony_init_ff(hdev); 1092a08c22c0SSven Eckelmann if (ret < 0) 1093a08c22c0SSven Eckelmann goto err_stop; 1094a08c22c0SSven Eckelmann 1095bd28ce00SJiri Slaby return 0; 1096bd28ce00SJiri Slaby err_stop: 10970a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 10980a286ef2SSven Eckelmann sony_leds_remove(hdev); 1099bd28ce00SJiri Slaby hid_hw_stop(hdev); 1100bd28ce00SJiri Slaby return ret; 1101bd28ce00SJiri Slaby } 1102bd28ce00SJiri Slaby 1103cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 1104cc6e0bbbSJiri Kosina { 1105f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1106f04d5140SColin Leitner 11070a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1108c5382519SSven Eckelmann sony_leds_remove(hdev); 1109f04d5140SColin Leitner 11109f323b68SSven Eckelmann sony_destroy_ff(hdev); 11119f323b68SSven Eckelmann 1112cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 1113cc6e0bbbSJiri Kosina } 1114cc6e0bbbSJiri Kosina 1115bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 1116816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1117816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 111835dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 111935dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 1120816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1121816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 1122cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 1123cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 1124a4649184SFernando Luis Vázquez Cao { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 1125a4649184SFernando Luis Vázquez Cao .driver_data = VAIO_RDESC_CONSTANT }, 1126f04d5140SColin Leitner /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 1127f04d5140SColin Leitner * Logitech joystick from the device descriptor. */ 1128f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 1129f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1130f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 1131f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1132078328daSJiri Kosina /* PS3 BD Remote Control */ 1133078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 1134078328daSJiri Kosina .driver_data = PS3REMOTE }, 1135078328daSJiri Kosina /* Logitech Harmony Adapter for PS3 */ 1136078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 1137078328daSJiri Kosina .driver_data = PS3REMOTE }, 11380bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 11390bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 11408ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 11410bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 11428ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 1143bd28ce00SJiri Slaby { } 1144bd28ce00SJiri Slaby }; 1145bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 1146bd28ce00SJiri Slaby 1147bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 1148bd28ce00SJiri Slaby .name = "sony", 1149bd28ce00SJiri Slaby .id_table = sony_devices, 1150f04d5140SColin Leitner .input_mapping = sony_mapping, 1151bd28ce00SJiri Slaby .probe = sony_probe, 1152cc6e0bbbSJiri Kosina .remove = sony_remove, 1153cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 1154c9e4d877SSimon Wood .raw_event = sony_raw_event 1155bd28ce00SJiri Slaby }; 1156f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 1157bd28ce00SJiri Slaby 1158bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 1159