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 36816651a7SAntonio Ospite #define VAIO_RDESC_CONSTANT (1 << 0) 37816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_USB (1 << 1) 38816651a7SAntonio Ospite #define SIXAXIS_CONTROLLER_BT (1 << 2) 39f04d5140SColin Leitner #define BUZZ_CONTROLLER (1 << 3) 40078328daSJiri Kosina #define PS3REMOTE (1 << 4) 41cc6e0bbbSJiri Kosina 4261ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 4361ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 4461ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 4561ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 4661ab44beSSimon Wood }; 4761ab44beSSimon Wood 48e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = { 49e57a67daSMauro Carvalho Chehab 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 50e57a67daSMauro Carvalho Chehab 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 51e57a67daSMauro Carvalho Chehab 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 52e57a67daSMauro Carvalho Chehab 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 53e57a67daSMauro Carvalho Chehab 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 54e57a67daSMauro Carvalho Chehab 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 55e57a67daSMauro Carvalho Chehab 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 56e57a67daSMauro Carvalho Chehab 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 57e57a67daSMauro Carvalho Chehab 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 58e57a67daSMauro Carvalho Chehab 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 59e57a67daSMauro Carvalho Chehab 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 60e57a67daSMauro Carvalho Chehab 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 61e57a67daSMauro Carvalho Chehab 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 62e57a67daSMauro Carvalho Chehab 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 63e57a67daSMauro Carvalho Chehab 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 64e57a67daSMauro Carvalho Chehab 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 65e57a67daSMauro Carvalho Chehab 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 66e57a67daSMauro Carvalho Chehab 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 67e57a67daSMauro Carvalho Chehab 0xb1, 0x02, 0xc0, 0xc0, 68e57a67daSMauro Carvalho Chehab }; 69e57a67daSMauro Carvalho Chehab 70078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 71078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 72078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 73078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 74078328daSJiri Kosina 75078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 76078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 77078328daSJiri Kosina 78078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 79078328daSJiri Kosina * number but it's not needed for correct operation */ 80078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 81078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 82078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 83078328daSJiri Kosina 84078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 85078328daSJiri Kosina * buttons multiple keypresses are allowed */ 86078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 87078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 88078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 89078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 90078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 91078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 92078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 93078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 94078328daSJiri Kosina 95078328daSJiri Kosina 0xC0, /* MEndCollection */ 96078328daSJiri Kosina 97078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 98078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 99078328daSJiri Kosina 100078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 101078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 102078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 103078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 104078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 105078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 106078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 107078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 108078328daSJiri Kosina 0x80, /* MInput */ 109078328daSJiri Kosina 110078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 111078328daSJiri Kosina * 0xff and 11th is for press indication */ 112078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 113078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 114078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 115078328daSJiri Kosina 116078328daSJiri Kosina /* 12th byte is for battery strength */ 117078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 118078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 119078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 120078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 121078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 122078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 123078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 124078328daSJiri Kosina 125078328daSJiri Kosina 0xC0, /* MEndCollection */ 126078328daSJiri Kosina 127078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 128078328daSJiri Kosina }; 129078328daSJiri Kosina 130078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 131078328daSJiri Kosina [0x01] = KEY_SELECT, 132078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 133078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 134078328daSJiri Kosina [0x04] = BTN_START, 135078328daSJiri Kosina [0x05] = KEY_UP, 136078328daSJiri Kosina [0x06] = KEY_RIGHT, 137078328daSJiri Kosina [0x07] = KEY_DOWN, 138078328daSJiri Kosina [0x08] = KEY_LEFT, 139078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 140078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 141078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 142078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 143078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 144078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 145078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 146078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 147078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 148078328daSJiri Kosina [0x14] = KEY_ENTER, 149078328daSJiri Kosina }; 150078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 151078328daSJiri Kosina [0x00] = KEY_1, 152078328daSJiri Kosina [0x01] = KEY_2, 153078328daSJiri Kosina [0x02] = KEY_3, 154078328daSJiri Kosina [0x03] = KEY_4, 155078328daSJiri Kosina [0x04] = KEY_5, 156078328daSJiri Kosina [0x05] = KEY_6, 157078328daSJiri Kosina [0x06] = KEY_7, 158078328daSJiri Kosina [0x07] = KEY_8, 159078328daSJiri Kosina [0x08] = KEY_9, 160078328daSJiri Kosina [0x09] = KEY_0, 161078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 162078328daSJiri Kosina [0x0f] = KEY_CLEAR, 163078328daSJiri Kosina [0x16] = KEY_EJECTCD, 164078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 165078328daSJiri Kosina [0x28] = KEY_TIME, 166078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 167078328daSJiri Kosina [0x31] = KEY_NEXT, 168078328daSJiri Kosina [0x32] = KEY_PLAY, 169078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 170078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 171078328daSJiri Kosina [0x38] = KEY_STOP, 172078328daSJiri Kosina [0x39] = KEY_PAUSE, 173078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 174078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 175078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 176078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 177078328daSJiri Kosina [0x64] = KEY_AUDIO, 178078328daSJiri Kosina [0x65] = KEY_ANGLE, 179078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 180078328daSJiri Kosina [0x80] = KEY_BLUE, 181078328daSJiri Kosina [0x81] = KEY_RED, 182078328daSJiri Kosina [0x82] = KEY_GREEN, 183078328daSJiri Kosina [0x83] = KEY_YELLOW, 184078328daSJiri Kosina }; 185078328daSJiri Kosina 186f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 187f04d5140SColin Leitner /* The controller has 4 remote buzzers, each with one LED and 5 188f04d5140SColin Leitner * buttons. 189f04d5140SColin Leitner * 190f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 191f04d5140SColin Leitner * 192f04d5140SColin Leitner * Key Offset 193f04d5140SColin Leitner * ------------------- 194f04d5140SColin Leitner * Buzz 1 195f04d5140SColin Leitner * Blue 5 196f04d5140SColin Leitner * Orange 4 197f04d5140SColin Leitner * Green 3 198f04d5140SColin Leitner * Yellow 2 199f04d5140SColin Leitner * 200f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 201f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 202f04d5140SColin Leitner */ 203f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 204f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 205f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 206f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 207f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 208f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 209f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 210f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 211f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 212f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 213f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 214f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 215f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 216f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 217f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 218f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 219f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 220f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 221f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 222f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 223f04d5140SColin Leitner }; 224f04d5140SColin Leitner 225cc6e0bbbSJiri Kosina struct sony_sc { 226cc6e0bbbSJiri Kosina unsigned long quirks; 227f04d5140SColin Leitner 228f04d5140SColin Leitner void *extra; 229f04d5140SColin Leitner }; 230f04d5140SColin Leitner 231f04d5140SColin Leitner struct buzz_extra { 232f04d5140SColin Leitner int led_state; 233f04d5140SColin Leitner struct led_classdev *leds[4]; 234cc6e0bbbSJiri Kosina }; 235cc6e0bbbSJiri Kosina 236078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 237078328daSJiri Kosina unsigned int *rsize) 238078328daSJiri Kosina { 239078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 240078328daSJiri Kosina return ps3remote_rdesc; 241078328daSJiri Kosina } 242078328daSJiri Kosina 243078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 244078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 245078328daSJiri Kosina unsigned long **bit, int *max) 246078328daSJiri Kosina { 247078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 248078328daSJiri Kosina 249078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 250078328daSJiri Kosina return -1; 251078328daSJiri Kosina 252078328daSJiri Kosina switch (usage->collection_index) { 253078328daSJiri Kosina case 1: 254078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 255078328daSJiri Kosina return -1; 256078328daSJiri Kosina 257078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 258078328daSJiri Kosina if (!key) 259078328daSJiri Kosina return -1; 260078328daSJiri Kosina break; 261078328daSJiri Kosina case 2: 262078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 263078328daSJiri Kosina return -1; 264078328daSJiri Kosina 265078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 266078328daSJiri Kosina if (!key) 267078328daSJiri Kosina return -1; 268078328daSJiri Kosina break; 269078328daSJiri Kosina default: 270078328daSJiri Kosina return -1; 271078328daSJiri Kosina } 272078328daSJiri Kosina 273078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 274078328daSJiri Kosina return 1; 275078328daSJiri Kosina } 276078328daSJiri Kosina 277078328daSJiri Kosina 278cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 27973e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 28073e4008dSNikolai Kondrashov unsigned int *rsize) 281cc6e0bbbSJiri Kosina { 282cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 283cc6e0bbbSJiri Kosina 28499d24902SFernando Luis Vázquez Cao /* 28599d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 28699d24902SFernando Luis Vázquez Cao * a constant non-data variable. 28799d24902SFernando Luis Vázquez Cao */ 28899d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 28999d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 29099d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 29199d24902SFernando Luis Vázquez Cao /* usage: mouse */ 29299d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 29399d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 29499d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 295a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 29699d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 297cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 298cc6e0bbbSJiri Kosina } 29961ab44beSSimon Wood 30061ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 30161ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 30261ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 30361ab44beSSimon Wood rdesc[83] == 0x75) { 30461ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 30561ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 30661ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 307e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 308e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 309e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 310e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 311e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 312e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 31361ab44beSSimon Wood } 314078328daSJiri Kosina 315078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 316078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 317078328daSJiri Kosina 31873e4008dSNikolai Kondrashov return rdesc; 319cc6e0bbbSJiri Kosina } 320cc6e0bbbSJiri Kosina 321c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 322c9e4d877SSimon Wood __u8 *rd, int size) 323c9e4d877SSimon Wood { 324c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 325c9e4d877SSimon Wood 326c9e4d877SSimon Wood /* Sixaxis HID report has acclerometers/gyro with MSByte first, this 327c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 328c9e4d877SSimon Wood */ 329c9e4d877SSimon Wood if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) && 330c9e4d877SSimon Wood rd[0] == 0x01 && size == 49) { 331c9e4d877SSimon Wood swap(rd[41], rd[42]); 332c9e4d877SSimon Wood swap(rd[43], rd[44]); 333c9e4d877SSimon Wood swap(rd[45], rd[46]); 334c9e4d877SSimon Wood swap(rd[47], rd[48]); 335c9e4d877SSimon Wood } 336c9e4d877SSimon Wood 337c9e4d877SSimon Wood return 0; 338c9e4d877SSimon Wood } 339c9e4d877SSimon Wood 340f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 341f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 342f04d5140SColin Leitner unsigned long **bit, int *max) 343f04d5140SColin Leitner { 344f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 345f04d5140SColin Leitner 346f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 347f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 348f04d5140SColin Leitner 349f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 350f04d5140SColin Leitner return -1; 351f04d5140SColin Leitner 352f04d5140SColin Leitner switch (usage->collection_index) { 353f04d5140SColin Leitner case 1: 354f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 355f04d5140SColin Leitner return -1; 356f04d5140SColin Leitner 357f04d5140SColin Leitner key = buzz_keymap[key]; 358f04d5140SColin Leitner if (!key) 359f04d5140SColin Leitner return -1; 360f04d5140SColin Leitner break; 361f04d5140SColin Leitner default: 362f04d5140SColin Leitner return -1; 363f04d5140SColin Leitner } 364f04d5140SColin Leitner 365f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 366f04d5140SColin Leitner return 1; 367f04d5140SColin Leitner } 368f04d5140SColin Leitner 369078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 370078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 371078328daSJiri Kosina 372f04d5140SColin Leitner return -1; 373f04d5140SColin Leitner } 374f04d5140SColin Leitner 3755710fabfSAntonio Ospite /* 3765710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 3775710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 3785710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 3795710fabfSAntonio Ospite * 3805710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 3815710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 3825710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 3835710fabfSAntonio Ospite * reports, humpf! 3845710fabfSAntonio Ospite */ 385569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 386569b10a5SAntonio Ospite size_t count, unsigned char report_type) 387569b10a5SAntonio Ospite { 388569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 389569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 390569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 391569b10a5SAntonio Ospite int report_id = buf[0]; 392569b10a5SAntonio Ospite int ret; 393569b10a5SAntonio Ospite 3945710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 3955710fabfSAntonio Ospite /* Don't send the Report ID */ 3965710fabfSAntonio Ospite buf++; 3975710fabfSAntonio Ospite count--; 3985710fabfSAntonio Ospite } 3995710fabfSAntonio Ospite 400569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 401569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 402569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 403569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 404569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 405569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 406569b10a5SAntonio Ospite 4075710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 4085710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 4095710fabfSAntonio Ospite ret++; 4105710fabfSAntonio Ospite 411569b10a5SAntonio Ospite return ret; 412569b10a5SAntonio Ospite } 413569b10a5SAntonio Ospite 414bd28ce00SJiri Slaby /* 415bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 416bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 417bd28ce00SJiri Slaby * events. 418bd28ce00SJiri Slaby */ 419816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 420bd28ce00SJiri Slaby { 421bd28ce00SJiri Slaby struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 422bd28ce00SJiri Slaby struct usb_device *dev = interface_to_usbdev(intf); 423bd28ce00SJiri Slaby __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber; 424bd28ce00SJiri Slaby int ret; 425bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 426bd28ce00SJiri Slaby 427bd28ce00SJiri Slaby if (!buf) 428bd28ce00SJiri Slaby return -ENOMEM; 429bd28ce00SJiri Slaby 430bd28ce00SJiri Slaby ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 431bd28ce00SJiri Slaby HID_REQ_GET_REPORT, 432bd28ce00SJiri Slaby USB_DIR_IN | USB_TYPE_CLASS | 433bd28ce00SJiri Slaby USB_RECIP_INTERFACE, 434bd28ce00SJiri Slaby (3 << 8) | 0xf2, ifnum, buf, 17, 435bd28ce00SJiri Slaby USB_CTRL_GET_TIMEOUT); 436bd28ce00SJiri Slaby if (ret < 0) 4374291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 438bd28ce00SJiri Slaby 439bd28ce00SJiri Slaby kfree(buf); 440bd28ce00SJiri Slaby 441bd28ce00SJiri Slaby return ret; 442bd28ce00SJiri Slaby } 443bd28ce00SJiri Slaby 444816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 445f9ce7c28SBastien Nocera { 446fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 447f9ce7c28SBastien Nocera return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 448f9ce7c28SBastien Nocera } 449f9ce7c28SBastien Nocera 450f04d5140SColin Leitner static void buzz_set_leds(struct hid_device *hdev, int leds) 451f04d5140SColin Leitner { 452f04d5140SColin Leitner struct list_head *report_list = 453f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 454f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 455f04d5140SColin Leitner struct hid_report, list); 456f04d5140SColin Leitner __s32 *value = report->field[0]->value; 457f04d5140SColin Leitner 458f04d5140SColin Leitner value[0] = 0x00; 459f04d5140SColin Leitner value[1] = (leds & 1) ? 0xff : 0x00; 460f04d5140SColin Leitner value[2] = (leds & 2) ? 0xff : 0x00; 461f04d5140SColin Leitner value[3] = (leds & 4) ? 0xff : 0x00; 462f04d5140SColin Leitner value[4] = (leds & 8) ? 0xff : 0x00; 463f04d5140SColin Leitner value[5] = 0x00; 464f04d5140SColin Leitner value[6] = 0x00; 465f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 466f04d5140SColin Leitner } 467f04d5140SColin Leitner 468f04d5140SColin Leitner static void buzz_led_set_brightness(struct led_classdev *led, 469f04d5140SColin Leitner enum led_brightness value) 470f04d5140SColin Leitner { 471f04d5140SColin Leitner struct device *dev = led->dev->parent; 472f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 473f04d5140SColin Leitner struct sony_sc *drv_data; 474f04d5140SColin Leitner struct buzz_extra *buzz; 475f04d5140SColin Leitner 476f04d5140SColin Leitner int n; 477f04d5140SColin Leitner 478f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 479f04d5140SColin Leitner if (!drv_data || !drv_data->extra) { 480f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 481f04d5140SColin Leitner return; 482f04d5140SColin Leitner } 483f04d5140SColin Leitner buzz = drv_data->extra; 484f04d5140SColin Leitner 485f04d5140SColin Leitner for (n = 0; n < 4; n++) { 486f04d5140SColin Leitner if (led == buzz->leds[n]) { 487f04d5140SColin Leitner int on = !! (buzz->led_state & (1 << n)); 488f04d5140SColin Leitner if (value == LED_OFF && on) { 489f04d5140SColin Leitner buzz->led_state &= ~(1 << n); 490f04d5140SColin Leitner buzz_set_leds(hdev, buzz->led_state); 491f04d5140SColin Leitner } else if (value != LED_OFF && !on) { 492f04d5140SColin Leitner buzz->led_state |= (1 << n); 493f04d5140SColin Leitner buzz_set_leds(hdev, buzz->led_state); 494f04d5140SColin Leitner } 495f04d5140SColin Leitner break; 496f04d5140SColin Leitner } 497f04d5140SColin Leitner } 498f04d5140SColin Leitner } 499f04d5140SColin Leitner 500f04d5140SColin Leitner static enum led_brightness buzz_led_get_brightness(struct led_classdev *led) 501f04d5140SColin Leitner { 502f04d5140SColin Leitner struct device *dev = led->dev->parent; 503f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 504f04d5140SColin Leitner struct sony_sc *drv_data; 505f04d5140SColin Leitner struct buzz_extra *buzz; 506f04d5140SColin Leitner 507f04d5140SColin Leitner int n; 508f04d5140SColin Leitner int on = 0; 509f04d5140SColin Leitner 510f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 511f04d5140SColin Leitner if (!drv_data || !drv_data->extra) { 512f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 513f04d5140SColin Leitner return LED_OFF; 514f04d5140SColin Leitner } 515f04d5140SColin Leitner buzz = drv_data->extra; 516f04d5140SColin Leitner 517f04d5140SColin Leitner for (n = 0; n < 4; n++) { 518f04d5140SColin Leitner if (led == buzz->leds[n]) { 519f04d5140SColin Leitner on = !! (buzz->led_state & (1 << n)); 520f04d5140SColin Leitner break; 521f04d5140SColin Leitner } 522f04d5140SColin Leitner } 523f04d5140SColin Leitner 524f04d5140SColin Leitner return on ? LED_FULL : LED_OFF; 525f04d5140SColin Leitner } 526f04d5140SColin Leitner 527f04d5140SColin Leitner static int buzz_init(struct hid_device *hdev) 528f04d5140SColin Leitner { 529f04d5140SColin Leitner struct sony_sc *drv_data; 530f04d5140SColin Leitner struct buzz_extra *buzz; 53140e32ee6SJiri Kosina int n, ret = 0; 53240e32ee6SJiri Kosina struct led_classdev *led; 53340e32ee6SJiri Kosina size_t name_sz; 53440e32ee6SJiri Kosina char *name; 535f04d5140SColin Leitner 536f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 537f04d5140SColin Leitner BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); 538f04d5140SColin Leitner 539f04d5140SColin Leitner buzz = kzalloc(sizeof(*buzz), GFP_KERNEL); 540f04d5140SColin Leitner if (!buzz) { 541f04d5140SColin Leitner hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); 542f04d5140SColin Leitner return -ENOMEM; 543f04d5140SColin Leitner } 544f04d5140SColin Leitner drv_data->extra = buzz; 545f04d5140SColin Leitner 546f04d5140SColin Leitner /* Clear LEDs as we have no way of reading their initial state. This is 547f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 548f04d5140SColin Leitner * LEDs to on */ 549f04d5140SColin Leitner buzz_set_leds(hdev, 0x00); 550f04d5140SColin Leitner 551f04d5140SColin Leitner name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1; 552f04d5140SColin Leitner 553f04d5140SColin Leitner for (n = 0; n < 4; n++) { 554f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 555f04d5140SColin Leitner if (!led) { 556f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 557f04d5140SColin Leitner goto error_leds; 558f04d5140SColin Leitner } 559f04d5140SColin Leitner 560f04d5140SColin Leitner name = (void *)(&led[1]); 561f04d5140SColin Leitner snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1); 562f04d5140SColin Leitner led->name = name; 563f04d5140SColin Leitner led->brightness = 0; 564f04d5140SColin Leitner led->max_brightness = 1; 565f04d5140SColin Leitner led->brightness_get = buzz_led_get_brightness; 566f04d5140SColin Leitner led->brightness_set = buzz_led_set_brightness; 567f04d5140SColin Leitner 568f04d5140SColin Leitner if (led_classdev_register(&hdev->dev, led)) { 569f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 570f04d5140SColin Leitner kfree(led); 571f04d5140SColin Leitner goto error_leds; 572f04d5140SColin Leitner } 573f04d5140SColin Leitner 574f04d5140SColin Leitner buzz->leds[n] = led; 575f04d5140SColin Leitner } 576f04d5140SColin Leitner 577f04d5140SColin Leitner return ret; 578f04d5140SColin Leitner 579f04d5140SColin Leitner error_leds: 580f04d5140SColin Leitner for (n = 0; n < 4; n++) { 581f04d5140SColin Leitner led = buzz->leds[n]; 582f04d5140SColin Leitner buzz->leds[n] = NULL; 583f04d5140SColin Leitner if (!led) 584f04d5140SColin Leitner continue; 585f04d5140SColin Leitner led_classdev_unregister(led); 586f04d5140SColin Leitner kfree(led); 587f04d5140SColin Leitner } 588f04d5140SColin Leitner 589f04d5140SColin Leitner kfree(drv_data->extra); 590f04d5140SColin Leitner drv_data->extra = NULL; 591f04d5140SColin Leitner return ret; 592f04d5140SColin Leitner } 593f04d5140SColin Leitner 594f04d5140SColin Leitner static void buzz_remove(struct hid_device *hdev) 595f04d5140SColin Leitner { 596f04d5140SColin Leitner struct sony_sc *drv_data; 597f04d5140SColin Leitner struct buzz_extra *buzz; 59840e32ee6SJiri Kosina struct led_classdev *led; 59940e32ee6SJiri Kosina int n; 600f04d5140SColin Leitner 601f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 602f04d5140SColin Leitner BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); 603f04d5140SColin Leitner 604f04d5140SColin Leitner buzz = drv_data->extra; 605f04d5140SColin Leitner 606f04d5140SColin Leitner for (n = 0; n < 4; n++) { 607f04d5140SColin Leitner led = buzz->leds[n]; 608f04d5140SColin Leitner buzz->leds[n] = NULL; 609f04d5140SColin Leitner if (!led) 610f04d5140SColin Leitner continue; 611f04d5140SColin Leitner led_classdev_unregister(led); 612f04d5140SColin Leitner kfree(led); 613f04d5140SColin Leitner } 614f04d5140SColin Leitner 615f04d5140SColin Leitner kfree(drv_data->extra); 616f04d5140SColin Leitner drv_data->extra = NULL; 617f04d5140SColin Leitner } 618f04d5140SColin Leitner 619bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 620bd28ce00SJiri Slaby { 621bd28ce00SJiri Slaby int ret; 622cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 623cc6e0bbbSJiri Kosina struct sony_sc *sc; 624f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 625cc6e0bbbSJiri Kosina 626*abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 627cc6e0bbbSJiri Kosina if (sc == NULL) { 6284291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 629cc6e0bbbSJiri Kosina return -ENOMEM; 630cc6e0bbbSJiri Kosina } 631cc6e0bbbSJiri Kosina 632cc6e0bbbSJiri Kosina sc->quirks = quirks; 633cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 634bd28ce00SJiri Slaby 635bd28ce00SJiri Slaby ret = hid_parse(hdev); 636bd28ce00SJiri Slaby if (ret) { 6374291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 638*abf832bfSBenjamin Tissoires return ret; 639bd28ce00SJiri Slaby } 640bd28ce00SJiri Slaby 641f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 642f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 643f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 644f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 645f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 646f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 647f04d5140SColin Leitner 648f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 649bd28ce00SJiri Slaby if (ret) { 6504291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 651*abf832bfSBenjamin Tissoires return ret; 652bd28ce00SJiri Slaby } 653bd28ce00SJiri Slaby 654569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 655569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 656816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 657569b10a5SAntonio Ospite } 658816651a7SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 659816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 660f04d5140SColin Leitner else if (sc->quirks & BUZZ_CONTROLLER) 661f04d5140SColin Leitner ret = buzz_init(hdev); 662816651a7SAntonio Ospite else 663f9ce7c28SBastien Nocera ret = 0; 664f9ce7c28SBastien Nocera 6654dfdc464SJiri Kosina if (ret < 0) 666bd28ce00SJiri Slaby goto err_stop; 667bd28ce00SJiri Slaby 668bd28ce00SJiri Slaby return 0; 669bd28ce00SJiri Slaby err_stop: 670bd28ce00SJiri Slaby hid_hw_stop(hdev); 671bd28ce00SJiri Slaby return ret; 672bd28ce00SJiri Slaby } 673bd28ce00SJiri Slaby 674cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 675cc6e0bbbSJiri Kosina { 676f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 677f04d5140SColin Leitner 678f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) 679f04d5140SColin Leitner buzz_remove(hdev); 680f04d5140SColin Leitner 681cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 682cc6e0bbbSJiri Kosina } 683cc6e0bbbSJiri Kosina 684bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 685816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 686816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 68735dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 68835dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 689816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 690816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 691cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 692cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 693a4649184SFernando Luis Vázquez Cao { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 694a4649184SFernando Luis Vázquez Cao .driver_data = VAIO_RDESC_CONSTANT }, 695f04d5140SColin Leitner /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 696f04d5140SColin Leitner * Logitech joystick from the device descriptor. */ 697f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 698f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 699f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 700f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 701078328daSJiri Kosina /* PS3 BD Remote Control */ 702078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 703078328daSJiri Kosina .driver_data = PS3REMOTE }, 704078328daSJiri Kosina /* Logitech Harmony Adapter for PS3 */ 705078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 706078328daSJiri Kosina .driver_data = PS3REMOTE }, 707bd28ce00SJiri Slaby { } 708bd28ce00SJiri Slaby }; 709bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 710bd28ce00SJiri Slaby 711bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 712bd28ce00SJiri Slaby .name = "sony", 713bd28ce00SJiri Slaby .id_table = sony_devices, 714f04d5140SColin Leitner .input_mapping = sony_mapping, 715bd28ce00SJiri Slaby .probe = sony_probe, 716cc6e0bbbSJiri Kosina .remove = sony_remove, 717cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 718c9e4d877SSimon Wood .raw_event = sony_raw_event 719bd28ce00SJiri Slaby }; 720f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 721bd28ce00SJiri Slaby 722bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 723