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 76078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 77078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 78078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 79078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 80078328daSJiri Kosina 81078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 82078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 83078328daSJiri Kosina 84078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 85078328daSJiri Kosina * number but it's not needed for correct operation */ 86078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 87078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 88078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 89078328daSJiri Kosina 90078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 91078328daSJiri Kosina * buttons multiple keypresses are allowed */ 92078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 93078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 94078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 95078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 96078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 97078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 98078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 99078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 100078328daSJiri Kosina 101078328daSJiri Kosina 0xC0, /* MEndCollection */ 102078328daSJiri Kosina 103078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 104078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 105078328daSJiri Kosina 106078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 107078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 108078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 109078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 110078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 111078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 112078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 113078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 114078328daSJiri Kosina 0x80, /* MInput */ 115078328daSJiri Kosina 116078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 117078328daSJiri Kosina * 0xff and 11th is for press indication */ 118078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 119078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 120078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 121078328daSJiri Kosina 122078328daSJiri Kosina /* 12th byte is for battery strength */ 123078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 124078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 125078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 126078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 127078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 128078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 129078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 130078328daSJiri Kosina 131078328daSJiri Kosina 0xC0, /* MEndCollection */ 132078328daSJiri Kosina 133078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 134078328daSJiri Kosina }; 135078328daSJiri Kosina 136078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 137078328daSJiri Kosina [0x01] = KEY_SELECT, 138078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 139078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 140078328daSJiri Kosina [0x04] = BTN_START, 141078328daSJiri Kosina [0x05] = KEY_UP, 142078328daSJiri Kosina [0x06] = KEY_RIGHT, 143078328daSJiri Kosina [0x07] = KEY_DOWN, 144078328daSJiri Kosina [0x08] = KEY_LEFT, 145078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 146078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 147078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 148078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 149078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 150078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 151078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 152078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 153078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 154078328daSJiri Kosina [0x14] = KEY_ENTER, 155078328daSJiri Kosina }; 156078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 157078328daSJiri Kosina [0x00] = KEY_1, 158078328daSJiri Kosina [0x01] = KEY_2, 159078328daSJiri Kosina [0x02] = KEY_3, 160078328daSJiri Kosina [0x03] = KEY_4, 161078328daSJiri Kosina [0x04] = KEY_5, 162078328daSJiri Kosina [0x05] = KEY_6, 163078328daSJiri Kosina [0x06] = KEY_7, 164078328daSJiri Kosina [0x07] = KEY_8, 165078328daSJiri Kosina [0x08] = KEY_9, 166078328daSJiri Kosina [0x09] = KEY_0, 167078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 168078328daSJiri Kosina [0x0f] = KEY_CLEAR, 169078328daSJiri Kosina [0x16] = KEY_EJECTCD, 170078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 171078328daSJiri Kosina [0x28] = KEY_TIME, 172078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 173078328daSJiri Kosina [0x31] = KEY_NEXT, 174078328daSJiri Kosina [0x32] = KEY_PLAY, 175078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 176078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 177078328daSJiri Kosina [0x38] = KEY_STOP, 178078328daSJiri Kosina [0x39] = KEY_PAUSE, 179078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 180078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 181078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 182078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 183078328daSJiri Kosina [0x64] = KEY_AUDIO, 184078328daSJiri Kosina [0x65] = KEY_ANGLE, 185078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 186078328daSJiri Kosina [0x80] = KEY_BLUE, 187078328daSJiri Kosina [0x81] = KEY_RED, 188078328daSJiri Kosina [0x82] = KEY_GREEN, 189078328daSJiri Kosina [0x83] = KEY_YELLOW, 190078328daSJiri Kosina }; 191078328daSJiri Kosina 192f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 193f04d5140SColin Leitner /* The controller has 4 remote buzzers, each with one LED and 5 194f04d5140SColin Leitner * buttons. 195f04d5140SColin Leitner * 196f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 197f04d5140SColin Leitner * 198f04d5140SColin Leitner * Key Offset 199f04d5140SColin Leitner * ------------------- 200f04d5140SColin Leitner * Buzz 1 201f04d5140SColin Leitner * Blue 5 202f04d5140SColin Leitner * Orange 4 203f04d5140SColin Leitner * Green 3 204f04d5140SColin Leitner * Yellow 2 205f04d5140SColin Leitner * 206f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 207f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 208f04d5140SColin Leitner */ 209f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 210f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 211f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 212f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 213f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 214f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 215f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 216f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 217f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 218f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 219f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 220f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 221f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 222f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 223f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 224f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 225f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 226f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 227f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 228f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 229f04d5140SColin Leitner }; 230f04d5140SColin Leitner 231cc6e0bbbSJiri Kosina struct sony_sc { 2320a286ef2SSven Eckelmann struct hid_device *hdev; 23360781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 234cc6e0bbbSJiri Kosina unsigned long quirks; 2350a286ef2SSven Eckelmann struct work_struct state_worker; 236f04d5140SColin Leitner 2379f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 2389f323b68SSven Eckelmann __u8 left; 2399f323b68SSven Eckelmann __u8 right; 2409f323b68SSven Eckelmann #endif 2419f323b68SSven Eckelmann 24260781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 24360781cf4SFrank Praznik __u8 led_count; 244cc6e0bbbSJiri Kosina }; 245cc6e0bbbSJiri Kosina 246078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 247078328daSJiri Kosina unsigned int *rsize) 248078328daSJiri Kosina { 249078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 250078328daSJiri Kosina return ps3remote_rdesc; 251078328daSJiri Kosina } 252078328daSJiri Kosina 253078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 254078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 255078328daSJiri Kosina unsigned long **bit, int *max) 256078328daSJiri Kosina { 257078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 258078328daSJiri Kosina 259078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 260078328daSJiri Kosina return -1; 261078328daSJiri Kosina 262078328daSJiri Kosina switch (usage->collection_index) { 263078328daSJiri Kosina case 1: 264078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 265078328daSJiri Kosina return -1; 266078328daSJiri Kosina 267078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 268078328daSJiri Kosina if (!key) 269078328daSJiri Kosina return -1; 270078328daSJiri Kosina break; 271078328daSJiri Kosina case 2: 272078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 273078328daSJiri Kosina return -1; 274078328daSJiri Kosina 275078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 276078328daSJiri Kosina if (!key) 277078328daSJiri Kosina return -1; 278078328daSJiri Kosina break; 279078328daSJiri Kosina default: 280078328daSJiri Kosina return -1; 281078328daSJiri Kosina } 282078328daSJiri Kosina 283078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 284078328daSJiri Kosina return 1; 285078328daSJiri Kosina } 286078328daSJiri Kosina 287078328daSJiri Kosina 288cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 28973e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 29073e4008dSNikolai Kondrashov unsigned int *rsize) 291cc6e0bbbSJiri Kosina { 292cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 293cc6e0bbbSJiri Kosina 29499d24902SFernando Luis Vázquez Cao /* 29599d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 29699d24902SFernando Luis Vázquez Cao * a constant non-data variable. 29799d24902SFernando Luis Vázquez Cao */ 29899d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 29999d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 30099d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 30199d24902SFernando Luis Vázquez Cao /* usage: mouse */ 30299d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 30399d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 30499d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 305a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 30699d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 307cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 308cc6e0bbbSJiri Kosina } 30961ab44beSSimon Wood 31061ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 31161ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 31261ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 31361ab44beSSimon Wood rdesc[83] == 0x75) { 31461ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 31561ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 31661ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 317e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 318e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 319e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 320e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 321e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 322e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 32361ab44beSSimon Wood } 324078328daSJiri Kosina 325078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 326078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 327078328daSJiri Kosina 32873e4008dSNikolai Kondrashov return rdesc; 329cc6e0bbbSJiri Kosina } 330cc6e0bbbSJiri Kosina 331c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 332c9e4d877SSimon Wood __u8 *rd, int size) 333c9e4d877SSimon Wood { 334c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 335c9e4d877SSimon Wood 336c9e4d877SSimon Wood /* Sixaxis HID report has acclerometers/gyro with MSByte first, this 337c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 338c9e4d877SSimon Wood */ 339c9e4d877SSimon Wood if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) && 340c9e4d877SSimon Wood rd[0] == 0x01 && size == 49) { 341c9e4d877SSimon Wood swap(rd[41], rd[42]); 342c9e4d877SSimon Wood swap(rd[43], rd[44]); 343c9e4d877SSimon Wood swap(rd[45], rd[46]); 344c9e4d877SSimon Wood swap(rd[47], rd[48]); 345c9e4d877SSimon Wood } 346c9e4d877SSimon Wood 347c9e4d877SSimon Wood return 0; 348c9e4d877SSimon Wood } 349c9e4d877SSimon Wood 350f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 351f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 352f04d5140SColin Leitner unsigned long **bit, int *max) 353f04d5140SColin Leitner { 354f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 355f04d5140SColin Leitner 356f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 357f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 358f04d5140SColin Leitner 359f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 360f04d5140SColin Leitner return -1; 361f04d5140SColin Leitner 362f04d5140SColin Leitner switch (usage->collection_index) { 363f04d5140SColin Leitner case 1: 364f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 365f04d5140SColin Leitner return -1; 366f04d5140SColin Leitner 367f04d5140SColin Leitner key = buzz_keymap[key]; 368f04d5140SColin Leitner if (!key) 369f04d5140SColin Leitner return -1; 370f04d5140SColin Leitner break; 371f04d5140SColin Leitner default: 372f04d5140SColin Leitner return -1; 373f04d5140SColin Leitner } 374f04d5140SColin Leitner 375f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 376f04d5140SColin Leitner return 1; 377f04d5140SColin Leitner } 378f04d5140SColin Leitner 379078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 380078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 381078328daSJiri Kosina 3826f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 3836f498018SBenjamin Tissoires return 0; 384f04d5140SColin Leitner } 385f04d5140SColin Leitner 3865710fabfSAntonio Ospite /* 3875710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 3885710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 3895710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 3905710fabfSAntonio Ospite * 3915710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 3925710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 3935710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 3945710fabfSAntonio Ospite * reports, humpf! 3955710fabfSAntonio Ospite */ 396569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 397569b10a5SAntonio Ospite size_t count, unsigned char report_type) 398569b10a5SAntonio Ospite { 399569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 400569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 401569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 402569b10a5SAntonio Ospite int report_id = buf[0]; 403569b10a5SAntonio Ospite int ret; 404569b10a5SAntonio Ospite 4055710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 4065710fabfSAntonio Ospite /* Don't send the Report ID */ 4075710fabfSAntonio Ospite buf++; 4085710fabfSAntonio Ospite count--; 4095710fabfSAntonio Ospite } 4105710fabfSAntonio Ospite 411569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 412569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 413569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 414569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 415569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 416569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 417569b10a5SAntonio Ospite 4185710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 4195710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 4205710fabfSAntonio Ospite ret++; 4215710fabfSAntonio Ospite 422569b10a5SAntonio Ospite return ret; 423569b10a5SAntonio Ospite } 424569b10a5SAntonio Ospite 425bd28ce00SJiri Slaby /* 426bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 427bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 428bd28ce00SJiri Slaby * events. 429bd28ce00SJiri Slaby */ 430816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 431bd28ce00SJiri Slaby { 432bd28ce00SJiri Slaby int ret; 433bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 434bd28ce00SJiri Slaby 435bd28ce00SJiri Slaby if (!buf) 436bd28ce00SJiri Slaby return -ENOMEM; 437bd28ce00SJiri Slaby 438f204828aSBenjamin Tissoires ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT); 439f204828aSBenjamin Tissoires 440bd28ce00SJiri Slaby if (ret < 0) 4414291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 442bd28ce00SJiri Slaby 443bd28ce00SJiri Slaby kfree(buf); 444bd28ce00SJiri Slaby 445bd28ce00SJiri Slaby return ret; 446bd28ce00SJiri Slaby } 447bd28ce00SJiri Slaby 448816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 449f9ce7c28SBastien Nocera { 450fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 451f9ce7c28SBastien Nocera return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 452f9ce7c28SBastien Nocera } 453f9ce7c28SBastien Nocera 45460781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 455f04d5140SColin Leitner { 456f04d5140SColin Leitner struct list_head *report_list = 457f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 458f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 459f04d5140SColin Leitner struct hid_report, list); 460f04d5140SColin Leitner __s32 *value = report->field[0]->value; 461f04d5140SColin Leitner 462f04d5140SColin Leitner value[0] = 0x00; 46360781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 46460781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 46560781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 46660781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 467f04d5140SColin Leitner value[5] = 0x00; 468f04d5140SColin Leitner value[6] = 0x00; 469f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 470f04d5140SColin Leitner } 471f04d5140SColin Leitner 47260781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) 4730a286ef2SSven Eckelmann { 4740a286ef2SSven Eckelmann struct sony_sc *drv_data = hid_get_drvdata(hdev); 47560781cf4SFrank Praznik int n; 4760a286ef2SSven Eckelmann 47760781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 47860781cf4SFrank Praznik 47960781cf4SFrank Praznik if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { 4800a286ef2SSven Eckelmann buzz_set_leds(hdev, leds); 48160781cf4SFrank Praznik } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) || 4828ab1676bSFrank Praznik (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) { 48360781cf4SFrank Praznik for (n = 0; n < count; n++) 48460781cf4SFrank Praznik drv_data->led_state[n] = leds[n]; 4850a286ef2SSven Eckelmann schedule_work(&drv_data->state_worker); 4860a286ef2SSven Eckelmann } 4870a286ef2SSven Eckelmann } 4880a286ef2SSven Eckelmann 489c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 490f04d5140SColin Leitner enum led_brightness value) 491f04d5140SColin Leitner { 492f04d5140SColin Leitner struct device *dev = led->dev->parent; 493f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 494f04d5140SColin Leitner struct sony_sc *drv_data; 495f04d5140SColin Leitner 496f04d5140SColin Leitner int n; 497f04d5140SColin Leitner 498f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 4992251b85fSSven Eckelmann if (!drv_data) { 500f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 501f04d5140SColin Leitner return; 502f04d5140SColin Leitner } 503f04d5140SColin Leitner 50460781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 5052251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 50660781cf4SFrank Praznik if (value != drv_data->led_state[n]) { 50760781cf4SFrank Praznik drv_data->led_state[n] = value; 50860781cf4SFrank Praznik sony_set_leds(hdev, drv_data->led_state, drv_data->led_count); 509f04d5140SColin Leitner } 510f04d5140SColin Leitner break; 511f04d5140SColin Leitner } 512f04d5140SColin Leitner } 513f04d5140SColin Leitner } 514f04d5140SColin Leitner 515c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 516f04d5140SColin Leitner { 517f04d5140SColin Leitner struct device *dev = led->dev->parent; 518f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 519f04d5140SColin Leitner struct sony_sc *drv_data; 520f04d5140SColin Leitner 521f04d5140SColin Leitner int n; 522f04d5140SColin Leitner int on = 0; 523f04d5140SColin Leitner 524f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 5252251b85fSSven Eckelmann if (!drv_data) { 526f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 527f04d5140SColin Leitner return LED_OFF; 528f04d5140SColin Leitner } 529f04d5140SColin Leitner 53060781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 5312251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 53260781cf4SFrank Praznik on = !!(drv_data->led_state[n]); 533f04d5140SColin Leitner break; 534f04d5140SColin Leitner } 535f04d5140SColin Leitner } 536f04d5140SColin Leitner 537f04d5140SColin Leitner return on ? LED_FULL : LED_OFF; 538f04d5140SColin Leitner } 539f04d5140SColin Leitner 5400a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev) 5410a286ef2SSven Eckelmann { 5420a286ef2SSven Eckelmann struct sony_sc *drv_data; 5430a286ef2SSven Eckelmann struct led_classdev *led; 5440a286ef2SSven Eckelmann int n; 5450a286ef2SSven Eckelmann 5460a286ef2SSven Eckelmann drv_data = hid_get_drvdata(hdev); 5470a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 5480a286ef2SSven Eckelmann 54960781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 5500a286ef2SSven Eckelmann led = drv_data->leds[n]; 5510a286ef2SSven Eckelmann drv_data->leds[n] = NULL; 5520a286ef2SSven Eckelmann if (!led) 5530a286ef2SSven Eckelmann continue; 5540a286ef2SSven Eckelmann led_classdev_unregister(led); 5550a286ef2SSven Eckelmann kfree(led); 5560a286ef2SSven Eckelmann } 55760781cf4SFrank Praznik 55860781cf4SFrank Praznik drv_data->led_count = 0; 5590a286ef2SSven Eckelmann } 5600a286ef2SSven Eckelmann 561c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev) 562f04d5140SColin Leitner { 563f04d5140SColin Leitner struct sony_sc *drv_data; 56440e32ee6SJiri Kosina int n, ret = 0; 56560781cf4SFrank Praznik int max_brightness; 56640e32ee6SJiri Kosina struct led_classdev *led; 56740e32ee6SJiri Kosina size_t name_sz; 56840e32ee6SJiri Kosina char *name; 5690a286ef2SSven Eckelmann size_t name_len; 5700a286ef2SSven Eckelmann const char *name_fmt; 57160781cf4SFrank Praznik static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 }; 572f04d5140SColin Leitner 573f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 5740a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 575f04d5140SColin Leitner 5760a286ef2SSven Eckelmann if (drv_data->quirks & BUZZ_CONTROLLER) { 5770a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 5780a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 5799446edb9SKees Cook /* Validate expected report characteristics. */ 5809446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 5819446edb9SKees Cook return -ENODEV; 5820a286ef2SSven Eckelmann } else { 5830a286ef2SSven Eckelmann name_len = strlen("::sony#"); 5840a286ef2SSven Eckelmann name_fmt = "%s::sony%d"; 5850a286ef2SSven Eckelmann } 5869446edb9SKees Cook 5878ab1676bSFrank Praznik if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) { 58860781cf4SFrank Praznik drv_data->led_count = 3; 58960781cf4SFrank Praznik max_brightness = 255; 59060781cf4SFrank Praznik } else { 59160781cf4SFrank Praznik drv_data->led_count = 4; 59260781cf4SFrank Praznik max_brightness = 1; 59360781cf4SFrank Praznik } 59460781cf4SFrank Praznik 595f04d5140SColin Leitner /* Clear LEDs as we have no way of reading their initial state. This is 596f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 597f04d5140SColin Leitner * LEDs to on */ 59860781cf4SFrank Praznik sony_set_leds(hdev, initial_values, drv_data->led_count); 599f04d5140SColin Leitner 6000a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 601f04d5140SColin Leitner 60260781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 603f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 604f04d5140SColin Leitner if (!led) { 605f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 6068cd5fcdaSJulia Lawall ret = -ENOMEM; 607f04d5140SColin Leitner goto error_leds; 608f04d5140SColin Leitner } 609f04d5140SColin Leitner 610f04d5140SColin Leitner name = (void *)(&led[1]); 6110a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 612f04d5140SColin Leitner led->name = name; 613f04d5140SColin Leitner led->brightness = 0; 61460781cf4SFrank Praznik led->max_brightness = max_brightness; 615c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 616c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 617f04d5140SColin Leitner 6188cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 6198cd5fcdaSJulia Lawall if (ret) { 620f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 621f04d5140SColin Leitner kfree(led); 622f04d5140SColin Leitner goto error_leds; 623f04d5140SColin Leitner } 624f04d5140SColin Leitner 6252251b85fSSven Eckelmann drv_data->leds[n] = led; 626f04d5140SColin Leitner } 627f04d5140SColin Leitner 628f04d5140SColin Leitner return ret; 629f04d5140SColin Leitner 630f04d5140SColin Leitner error_leds: 6310a286ef2SSven Eckelmann sony_leds_remove(hdev); 632f04d5140SColin Leitner 633f04d5140SColin Leitner return ret; 634f04d5140SColin Leitner } 635f04d5140SColin Leitner 636cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 637a08c22c0SSven Eckelmann { 63892b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 639a08c22c0SSven Eckelmann unsigned char buf[] = { 640a08c22c0SSven Eckelmann 0x01, 641a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 6420a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 643a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 644a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 645a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 646a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 647a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 648a08c22c0SSven Eckelmann }; 6499f323b68SSven Eckelmann 6500a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 6510bd88dd3SFrank Praznik buf[3] = sc->right ? 1 : 0; 6529f323b68SSven Eckelmann buf[5] = sc->left; 6530a286ef2SSven Eckelmann #endif 6540a286ef2SSven Eckelmann 65560781cf4SFrank Praznik buf[10] |= sc->led_state[0] << 1; 65660781cf4SFrank Praznik buf[10] |= sc->led_state[1] << 2; 65760781cf4SFrank Praznik buf[10] |= sc->led_state[2] << 3; 65860781cf4SFrank Praznik buf[10] |= sc->led_state[3] << 4; 6599f323b68SSven Eckelmann 6609f323b68SSven Eckelmann sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf), 6619f323b68SSven Eckelmann HID_OUTPUT_REPORT); 6629f323b68SSven Eckelmann } 6639f323b68SSven Eckelmann 6640bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 6650bd88dd3SFrank Praznik { 6660bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 667*0da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 668*0da8ea65SFrank Praznik struct list_head *head, *list; 669*0da8ea65SFrank Praznik struct hid_report *report; 670*0da8ea65SFrank Praznik __s32 *value; 671*0da8ea65SFrank Praznik 672*0da8ea65SFrank Praznik list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 673*0da8ea65SFrank Praznik 674*0da8ea65SFrank Praznik list_for_each(head, list) { 675*0da8ea65SFrank Praznik report = list_entry(head, struct hid_report, list); 676*0da8ea65SFrank Praznik 677*0da8ea65SFrank Praznik /* Report 5 is used to send data to the controller via USB */ 678*0da8ea65SFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && report->id == 5) 679*0da8ea65SFrank Praznik break; 680*0da8ea65SFrank Praznik } 681*0da8ea65SFrank Praznik 682*0da8ea65SFrank Praznik if (head == list) { 683*0da8ea65SFrank Praznik hid_err(hdev, "Dualshock 4 output report not found\n"); 684*0da8ea65SFrank Praznik return; 685*0da8ea65SFrank Praznik } 686*0da8ea65SFrank Praznik 687*0da8ea65SFrank Praznik value = report->field[0]->value; 688*0da8ea65SFrank Praznik value[0] = 0x03; 6890bd88dd3SFrank Praznik 6900bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 691*0da8ea65SFrank Praznik value[3] = sc->right; 692*0da8ea65SFrank Praznik value[4] = sc->left; 6930bd88dd3SFrank Praznik #endif 6940bd88dd3SFrank Praznik 695*0da8ea65SFrank Praznik value[5] = sc->led_state[0]; 696*0da8ea65SFrank Praznik value[6] = sc->led_state[1]; 697*0da8ea65SFrank Praznik value[7] = sc->led_state[2]; 69860781cf4SFrank Praznik 699*0da8ea65SFrank Praznik hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 7000bd88dd3SFrank Praznik } 7010bd88dd3SFrank Praznik 7020a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 7039f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 7049f323b68SSven Eckelmann struct ff_effect *effect) 7059f323b68SSven Eckelmann { 706a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 7079f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 708a08c22c0SSven Eckelmann 709a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 710a08c22c0SSven Eckelmann return 0; 711a08c22c0SSven Eckelmann 7129f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 7130bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 714a08c22c0SSven Eckelmann 71592b5c411SSven Eckelmann schedule_work(&sc->state_worker); 7169f323b68SSven Eckelmann return 0; 717a08c22c0SSven Eckelmann } 718a08c22c0SSven Eckelmann 719a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 720a08c22c0SSven Eckelmann { 721a08c22c0SSven Eckelmann struct hid_input *hidinput = list_entry(hdev->inputs.next, 722a08c22c0SSven Eckelmann struct hid_input, list); 723a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 724a08c22c0SSven Eckelmann 725a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 726a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 727a08c22c0SSven Eckelmann } 728a08c22c0SSven Eckelmann 7299f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 7309f323b68SSven Eckelmann { 7319f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hdev); 7329f323b68SSven Eckelmann 73392b5c411SSven Eckelmann cancel_work_sync(&sc->state_worker); 7349f323b68SSven Eckelmann } 7359f323b68SSven Eckelmann 736a08c22c0SSven Eckelmann #else 737a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 738a08c22c0SSven Eckelmann { 739a08c22c0SSven Eckelmann return 0; 740a08c22c0SSven Eckelmann } 7419f323b68SSven Eckelmann 7429f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 7439f323b68SSven Eckelmann { 7449f323b68SSven Eckelmann } 745a08c22c0SSven Eckelmann #endif 746a08c22c0SSven Eckelmann 747bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 748bd28ce00SJiri Slaby { 749bd28ce00SJiri Slaby int ret; 750cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 751cc6e0bbbSJiri Kosina struct sony_sc *sc; 752f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 753cc6e0bbbSJiri Kosina 754abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 755cc6e0bbbSJiri Kosina if (sc == NULL) { 7564291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 757cc6e0bbbSJiri Kosina return -ENOMEM; 758cc6e0bbbSJiri Kosina } 759cc6e0bbbSJiri Kosina 760cc6e0bbbSJiri Kosina sc->quirks = quirks; 761cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 7620a286ef2SSven Eckelmann sc->hdev = hdev; 763bd28ce00SJiri Slaby 764bd28ce00SJiri Slaby ret = hid_parse(hdev); 765bd28ce00SJiri Slaby if (ret) { 7664291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 767abf832bfSBenjamin Tissoires return ret; 768bd28ce00SJiri Slaby } 769bd28ce00SJiri Slaby 770f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 771f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 772f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 773f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 774f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 775f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 776f04d5140SColin Leitner 777f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 778bd28ce00SJiri Slaby if (ret) { 7794291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 780abf832bfSBenjamin Tissoires return ret; 781bd28ce00SJiri Slaby } 782bd28ce00SJiri Slaby 783569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 784569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 785816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 786cad665a2SFrank Praznik INIT_WORK(&sc->state_worker, sixaxis_state_worker); 787569b10a5SAntonio Ospite } 788816651a7SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 789816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 7908ab1676bSFrank Praznik else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 791f9ce7c28SBastien Nocera ret = 0; 7920bd88dd3SFrank Praznik INIT_WORK(&sc->state_worker, dualshock4_state_worker); 7930bd88dd3SFrank Praznik } else { 7940bd88dd3SFrank Praznik ret = 0; 7950bd88dd3SFrank Praznik } 796f9ce7c28SBastien Nocera 7974dfdc464SJiri Kosina if (ret < 0) 798bd28ce00SJiri Slaby goto err_stop; 799bd28ce00SJiri Slaby 8000a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 8010a286ef2SSven Eckelmann ret = sony_leds_init(hdev); 8020a286ef2SSven Eckelmann if (ret < 0) 8030a286ef2SSven Eckelmann goto err_stop; 8040a286ef2SSven Eckelmann } 8050a286ef2SSven Eckelmann 806a08c22c0SSven Eckelmann ret = sony_init_ff(hdev); 807a08c22c0SSven Eckelmann if (ret < 0) 808a08c22c0SSven Eckelmann goto err_stop; 809a08c22c0SSven Eckelmann 810bd28ce00SJiri Slaby return 0; 811bd28ce00SJiri Slaby err_stop: 8120a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 8130a286ef2SSven Eckelmann sony_leds_remove(hdev); 814bd28ce00SJiri Slaby hid_hw_stop(hdev); 815bd28ce00SJiri Slaby return ret; 816bd28ce00SJiri Slaby } 817bd28ce00SJiri Slaby 818cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 819cc6e0bbbSJiri Kosina { 820f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 821f04d5140SColin Leitner 8220a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 823c5382519SSven Eckelmann sony_leds_remove(hdev); 824f04d5140SColin Leitner 8259f323b68SSven Eckelmann sony_destroy_ff(hdev); 8269f323b68SSven Eckelmann 827cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 828cc6e0bbbSJiri Kosina } 829cc6e0bbbSJiri Kosina 830bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 831816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 832816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 83335dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 83435dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 835816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 836816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 837cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 838cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 839a4649184SFernando Luis Vázquez Cao { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 840a4649184SFernando Luis Vázquez Cao .driver_data = VAIO_RDESC_CONSTANT }, 841f04d5140SColin Leitner /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 842f04d5140SColin Leitner * Logitech joystick from the device descriptor. */ 843f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 844f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 845f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 846f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 847078328daSJiri Kosina /* PS3 BD Remote Control */ 848078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 849078328daSJiri Kosina .driver_data = PS3REMOTE }, 850078328daSJiri Kosina /* Logitech Harmony Adapter for PS3 */ 851078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 852078328daSJiri Kosina .driver_data = PS3REMOTE }, 8530bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 8540bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 8558ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 8560bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 8578ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 858bd28ce00SJiri Slaby { } 859bd28ce00SJiri Slaby }; 860bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 861bd28ce00SJiri Slaby 862bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 863bd28ce00SJiri Slaby .name = "sony", 864bd28ce00SJiri Slaby .id_table = sony_devices, 865f04d5140SColin Leitner .input_mapping = sony_mapping, 866bd28ce00SJiri Slaby .probe = sony_probe, 867cc6e0bbbSJiri Kosina .remove = sony_remove, 868cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 869c9e4d877SSimon Wood .raw_event = sony_raw_event 870bd28ce00SJiri Slaby }; 871f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 872bd28ce00SJiri Slaby 873bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 874