1bd28ce00SJiri Slaby /* 2078328daSJiri Kosina * HID driver for Sony / PS2 / PS3 BD devices. 3bd28ce00SJiri Slaby * 4bd28ce00SJiri Slaby * Copyright (c) 1999 Andreas Gal 5bd28ce00SJiri Slaby * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6bd28ce00SJiri Slaby * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7bd28ce00SJiri Slaby * Copyright (c) 2008 Jiri Slaby 8078328daSJiri Kosina * Copyright (c) 2012 David Dillow <dave@thedillows.org> 9078328daSJiri Kosina * Copyright (c) 2006-2013 Jiri Kosina 10f04d5140SColin Leitner * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> 11bd28ce00SJiri Slaby */ 12bd28ce00SJiri Slaby 13bd28ce00SJiri Slaby /* 14bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 15bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 16bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 17bd28ce00SJiri Slaby * any later version. 18bd28ce00SJiri Slaby */ 19bd28ce00SJiri Slaby 20ad142b9eSFrank Praznik /* 21ad142b9eSFrank Praznik * NOTE: in order for the Sony PS3 BD Remote Control to be found by 22078328daSJiri Kosina * a Bluetooth host, the key combination Start+Enter has to be kept pressed 23078328daSJiri Kosina * for about 7 seconds with the Bluetooth Host Controller in discovering mode. 24078328daSJiri Kosina * 25078328daSJiri Kosina * There will be no PIN request from the device. 26078328daSJiri Kosina */ 27078328daSJiri Kosina 28bd28ce00SJiri Slaby #include <linux/device.h> 29bd28ce00SJiri Slaby #include <linux/hid.h> 30bd28ce00SJiri Slaby #include <linux/module.h> 315a0e3ad6STejun Heo #include <linux/slab.h> 3240e32ee6SJiri Kosina #include <linux/leds.h> 33d902f472SFrank Praznik #include <linux/power_supply.h> 34d902f472SFrank Praznik #include <linux/spinlock.h> 35d2d782fcSFrank Praznik #include <linux/list.h> 368025087aSFrank Praznik #include <linux/idr.h> 37e5606230SFrank Praznik #include <linux/input/mt.h> 38bd28ce00SJiri Slaby 39bd28ce00SJiri Slaby #include "hid-ids.h" 40bd28ce00SJiri Slaby 41f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 43f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 44f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 45f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 478ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 48cc6e0bbbSJiri Kosina 49fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 5068330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ 5168330d83SFrank Praznik DUALSHOCK4_CONTROLLER_BT) 52fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 5368330d83SFrank Praznik DUALSHOCK4_CONTROLLER) 54fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 55c8de9dbbSFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 5660781cf4SFrank Praznik 5760781cf4SFrank Praznik #define MAX_LEDS 4 580a286ef2SSven Eckelmann 59c607fb8dSAntonio Ospite static __u8 sixaxis_rdesc[] = { 60fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 61fb705a6dSAntonio Ospite 0x09, 0x04, /* Usage (Joystik), */ 62fb705a6dSAntonio Ospite 0xA1, 0x01, /* Collection (Application), */ 63fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 64fb705a6dSAntonio Ospite 0x85, 0x01, /* Report ID (1), */ 65fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 66fb705a6dSAntonio Ospite 0x95, 0x01, /* Report Count (1), */ 67fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 68fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 69fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 70fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 71fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 72fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 73fb705a6dSAntonio Ospite 0x25, 0x01, /* Logical Maximum (1), */ 74fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 75fb705a6dSAntonio Ospite 0x45, 0x01, /* Physical Maximum (1), */ 76fb705a6dSAntonio Ospite 0x05, 0x09, /* Usage Page (Button), */ 77fb705a6dSAntonio Ospite 0x19, 0x01, /* Usage Minimum (01h), */ 78fb705a6dSAntonio Ospite 0x29, 0x13, /* Usage Maximum (13h), */ 79fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 80fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 81fb705a6dSAntonio Ospite 0x95, 0x0D, /* Report Count (13), */ 82fb705a6dSAntonio Ospite 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 83fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 84fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 85fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 86fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 87fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 88fb705a6dSAntonio Ospite 0xA1, 0x00, /* Collection (Physical), */ 89fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 90fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 91fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 92fb705a6dSAntonio Ospite 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 93fb705a6dSAntonio Ospite 0x09, 0x30, /* Usage (X), */ 94fb705a6dSAntonio Ospite 0x09, 0x31, /* Usage (Y), */ 95fb705a6dSAntonio Ospite 0x09, 0x32, /* Usage (Z), */ 96fb705a6dSAntonio Ospite 0x09, 0x35, /* Usage (Rz), */ 97fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 98fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 99fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 100fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 101fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 102fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 103fb705a6dSAntonio Ospite 0x95, 0x0C, /* Report Count (12), */ 104fb705a6dSAntonio Ospite 0x81, 0x01, /* Input (Constant), */ 105fb705a6dSAntonio Ospite 0x75, 0x10, /* Report Size (16), */ 106fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 107fb705a6dSAntonio Ospite 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 108fb705a6dSAntonio Ospite 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ 109fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 110fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 111fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 112fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 113fb705a6dSAntonio Ospite 0x85, 0x02, /* Report ID (2), */ 114fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 115fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 116fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 117fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 118fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 119fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 120fb705a6dSAntonio Ospite 0x85, 0xEE, /* Report ID (238), */ 121fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 122fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 123fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 124fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 125fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 126fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 127fb705a6dSAntonio Ospite 0x85, 0xEF, /* Report ID (239), */ 128fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 129fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 130fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 131fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 132fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 133fb705a6dSAntonio Ospite 0xC0 /* End Collection */ 134e57a67daSMauro Carvalho Chehab }; 135e57a67daSMauro Carvalho Chehab 136ad142b9eSFrank Praznik /* 137ad142b9eSFrank Praznik * The default descriptor doesn't provide mapping for the accelerometers 13858d7027bSFrank Praznik * or orientation sensors. This fixed descriptor maps the accelerometers 13958d7027bSFrank Praznik * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors 14058d7027bSFrank Praznik * to usage values 0x43, 0x44 and 0x45. 14158d7027bSFrank Praznik */ 142ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = { 14358d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 14458d7027bSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 14558d7027bSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 14658d7027bSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 14758d7027bSFrank Praznik 0x09, 0x30, /* Usage (X), */ 14858d7027bSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 14958d7027bSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 15058d7027bSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 15158d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 15258d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 15358d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 15458d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 15558d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15658d7027bSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 15758d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 15858d7027bSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 15958d7027bSFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 16058d7027bSFrank Praznik 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 16158d7027bSFrank Praznik 0x65, 0x14, /* Unit (Degrees), */ 16258d7027bSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 16358d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 16458d7027bSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 16558d7027bSFrank Praznik 0x65, 0x00, /* Unit, */ 16658d7027bSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 16758d7027bSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 16858d7027bSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 16958d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 17058d7027bSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 17158d7027bSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 17258d7027bSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 17358d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 17458d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 17558d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 17658d7027bSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 17758d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 17858d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 179*fb291cbdSFrank Praznik 0x25, 0x3F, /* Logical Maximum (63), */ 18058d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 18158d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 18258d7027bSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 18358d7027bSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 18458d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 18558d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 18658d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 18758d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 18858d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 18958d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 19058d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 19158d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 19258d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 19358d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 19458d7027bSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 19558d7027bSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 19658d7027bSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 19758d7027bSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 19858d7027bSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 19958d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 20058d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 20158d7027bSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 20258d7027bSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 203*fb291cbdSFrank Praznik 0x16, 0x00, 0xE0, /* Logical Minimum (-8192), */ 204*fb291cbdSFrank Praznik 0x26, 0xFF, 0x1F, /* Logical Maximum (8191), */ 20558d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 20658d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 20758d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 20858d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 20958d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 210*fb291cbdSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 21158d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 21258d7027bSFrank Praznik 0x95, 0x27, /* Report Count (39), */ 21358d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 21458d7027bSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 21558d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 21658d7027bSFrank Praznik 0x95, 0x1F, /* Report Count (31), */ 21758d7027bSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 21858d7027bSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 21958d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 22058d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 22158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22258d7027bSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 22358d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 22458d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 22558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22658d7027bSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 22758d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 22858d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 22958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23058d7027bSFrank Praznik 0x85, 0x10, /* Report ID (16), */ 23158d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 23258d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 23358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23458d7027bSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 23558d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 23658d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 23758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23858d7027bSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 23958d7027bSFrank Praznik 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ 24058d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 24158d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 24258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24358d7027bSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 24458d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 24558d7027bSFrank Praznik 0x95, 0x16, /* Report Count (22), */ 24658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24758d7027bSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 24858d7027bSFrank Praznik 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ 24958d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 25058d7027bSFrank Praznik 0x95, 0x10, /* Report Count (16), */ 25158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25258d7027bSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 25358d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 25458d7027bSFrank Praznik 0x95, 0x2C, /* Report Count (44), */ 25558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25658d7027bSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 25758d7027bSFrank Praznik 0x85, 0x80, /* Report ID (128), */ 25858d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 25958d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 26058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26158d7027bSFrank Praznik 0x85, 0x81, /* Report ID (129), */ 26258d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 26358d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 26458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26558d7027bSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 26658d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 26758d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 26858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26958d7027bSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 27058d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 27158d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 27258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27358d7027bSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 27458d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 27558d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 27658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27758d7027bSFrank Praznik 0x85, 0x85, /* Report ID (133), */ 27858d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 27958d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 28058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28158d7027bSFrank Praznik 0x85, 0x86, /* Report ID (134), */ 28258d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 28358d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 28458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28558d7027bSFrank Praznik 0x85, 0x87, /* Report ID (135), */ 28658d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 28758d7027bSFrank Praznik 0x95, 0x23, /* Report Count (35), */ 28858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28958d7027bSFrank Praznik 0x85, 0x88, /* Report ID (136), */ 29058d7027bSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 29158d7027bSFrank Praznik 0x95, 0x22, /* Report Count (34), */ 29258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29358d7027bSFrank Praznik 0x85, 0x89, /* Report ID (137), */ 29458d7027bSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 29558d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 29658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29758d7027bSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 29858d7027bSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 29958d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 30058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30158d7027bSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 30258d7027bSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 30358d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 30458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30558d7027bSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 30658d7027bSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 30758d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 30858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30958d7027bSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 31058d7027bSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 31158d7027bSFrank Praznik 0x95, 0x0C, /* Report Count (12), */ 31258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31358d7027bSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 31458d7027bSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 31558d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 31658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31758d7027bSFrank Praznik 0x85, 0xA1, /* Report ID (161), */ 31858d7027bSFrank Praznik 0x09, 0x41, /* Usage (41h), */ 31958d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 32058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32158d7027bSFrank Praznik 0x85, 0xA2, /* Report ID (162), */ 32258d7027bSFrank Praznik 0x09, 0x42, /* Usage (42h), */ 32358d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 32458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32558d7027bSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 32658d7027bSFrank Praznik 0x09, 0x43, /* Usage (43h), */ 32758d7027bSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 32858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32958d7027bSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 33058d7027bSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 33158d7027bSFrank Praznik 0x95, 0x0D, /* Report Count (13), */ 33258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33358d7027bSFrank Praznik 0x85, 0xA5, /* Report ID (165), */ 33458d7027bSFrank Praznik 0x09, 0x45, /* Usage (45h), */ 33558d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 33658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33758d7027bSFrank Praznik 0x85, 0xA6, /* Report ID (166), */ 33858d7027bSFrank Praznik 0x09, 0x46, /* Usage (46h), */ 33958d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 34058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34158d7027bSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 34258d7027bSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 34358d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 34458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34558d7027bSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 34658d7027bSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 34758d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 34858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34958d7027bSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 35058d7027bSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 35158d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 35258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 35358d7027bSFrank Praznik 0x85, 0xA7, /* Report ID (167), */ 35458d7027bSFrank Praznik 0x09, 0x4A, /* Usage (4Ah), */ 35558d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 35658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 35758d7027bSFrank Praznik 0x85, 0xA8, /* Report ID (168), */ 35858d7027bSFrank Praznik 0x09, 0x4B, /* Usage (4Bh), */ 35958d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 36058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 36158d7027bSFrank Praznik 0x85, 0xA9, /* Report ID (169), */ 36258d7027bSFrank Praznik 0x09, 0x4C, /* Usage (4Ch), */ 36358d7027bSFrank Praznik 0x95, 0x08, /* Report Count (8), */ 36458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 36558d7027bSFrank Praznik 0x85, 0xAA, /* Report ID (170), */ 36658d7027bSFrank Praznik 0x09, 0x4E, /* Usage (4Eh), */ 36758d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 36858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 36958d7027bSFrank Praznik 0x85, 0xAB, /* Report ID (171), */ 37058d7027bSFrank Praznik 0x09, 0x4F, /* Usage (4Fh), */ 37158d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 37258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 37358d7027bSFrank Praznik 0x85, 0xAC, /* Report ID (172), */ 37458d7027bSFrank Praznik 0x09, 0x50, /* Usage (50h), */ 37558d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 37658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 37758d7027bSFrank Praznik 0x85, 0xAD, /* Report ID (173), */ 37858d7027bSFrank Praznik 0x09, 0x51, /* Usage (51h), */ 37958d7027bSFrank Praznik 0x95, 0x0B, /* Report Count (11), */ 38058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 38158d7027bSFrank Praznik 0x85, 0xAE, /* Report ID (174), */ 38258d7027bSFrank Praznik 0x09, 0x52, /* Usage (52h), */ 38358d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 38458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 38558d7027bSFrank Praznik 0x85, 0xAF, /* Report ID (175), */ 38658d7027bSFrank Praznik 0x09, 0x53, /* Usage (53h), */ 38758d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 38858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 38958d7027bSFrank Praznik 0x85, 0xB0, /* Report ID (176), */ 39058d7027bSFrank Praznik 0x09, 0x54, /* Usage (54h), */ 39158d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 39258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 39358d7027bSFrank Praznik 0xC0 /* End Collection */ 394ed19d8cfSFrank Praznik }; 395ed19d8cfSFrank Praznik 396ad142b9eSFrank Praznik /* 397ad142b9eSFrank Praznik * The default behavior of the Dualshock 4 is to send reports using report 398d829674dSFrank Praznik * type 1 when running over Bluetooth. However, as soon as it receives a 399d829674dSFrank Praznik * report of type 17 to set the LEDs or rumble it starts returning it's state 400d829674dSFrank Praznik * in report 17 instead of 1. Since report 17 is undefined in the default HID 401d829674dSFrank Praznik * descriptor the button and axis definitions must be moved to report 17 or 402d829674dSFrank Praznik * the HID layer won't process the received input once a report is sent. 403d829674dSFrank Praznik */ 404d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = { 405d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 406d829674dSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 407d829674dSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 408d829674dSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 409d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 410d829674dSFrank Praznik 0x95, 0x0A, /* Report Count (9), */ 411d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 412d829674dSFrank Praznik 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ 413d829674dSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 414d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 415d829674dSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 416d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 417d829674dSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 418d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 419d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 420d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 421d829674dSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 422d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 423d829674dSFrank Praznik 0x95, 0x28, /* Report Count (40), */ 424d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 425d829674dSFrank Praznik 0x85, 0x06, /* Report ID (6), */ 426d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 427d829674dSFrank Praznik 0x95, 0x34, /* Report Count (52), */ 428d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 429d829674dSFrank Praznik 0x85, 0x07, /* Report ID (7), */ 430d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 431d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 432d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 433d829674dSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 434d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 435d829674dSFrank Praznik 0x95, 0x2F, /* Report Count (47), */ 436d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 437d829674dSFrank Praznik 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ 438d829674dSFrank Praznik 0x85, 0x03, /* Report ID (3), */ 439d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 440d829674dSFrank Praznik 0x95, 0x26, /* Report Count (38), */ 441d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 442d829674dSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 443d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 444d829674dSFrank Praznik 0x95, 0x2E, /* Report Count (46), */ 445d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 446d829674dSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 447d829674dSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 448d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 449d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 450d829674dSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 451d829674dSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 452d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 453d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 454d829674dSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 455d829674dSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 456d829674dSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 457d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 458d829674dSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 459d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 460d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 461d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 462d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 463d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 464d829674dSFrank Praznik 0x09, 0x30, /* Usage (X), */ 465d829674dSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 466d829674dSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 467d829674dSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 468d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 469d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 470d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 471d829674dSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 472d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 473d829674dSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 474d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 475d829674dSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 476d829674dSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 477d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 478d829674dSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 479d829674dSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 480d829674dSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 481d829674dSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 482d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 483d829674dSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 484d829674dSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 485d829674dSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 486d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 487d829674dSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 488d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 489d829674dSFrank Praznik 0x81, 0x01, /* Input (Constant), */ 490d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 491d829674dSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 492d829674dSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 493d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 494d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 495d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 496d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 497d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 498d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 499d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 500d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 501d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 502d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 503d829674dSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 504d829674dSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 505d829674dSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 506d829674dSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 507d829674dSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 508d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 509d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 510d829674dSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 511d829674dSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 512*fb291cbdSFrank Praznik 0x16, 0x00, 0xE0, /* Logical Minimum (-8192), */ 513*fb291cbdSFrank Praznik 0x26, 0xFF, 0x1F, /* Logical Maximum (8191), */ 514d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 515d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 516d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 517d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 518d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 519d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 520d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 521d829674dSFrank Praznik 0x95, 0x31, /* Report Count (51), */ 522d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 523d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 524d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 525d829674dSFrank Praznik 0x95, 0x4D, /* Report Count (77), */ 526d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 527d829674dSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 528d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 529d829674dSFrank Praznik 0x95, 0x8D, /* Report Count (141), */ 530d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 531d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 532d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 533d829674dSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 534d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 535d829674dSFrank Praznik 0x95, 0xCD, /* Report Count (205), */ 536d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 537d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 538d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 539d829674dSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 540d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 541d829674dSFrank Praznik 0x96, 0x0D, 0x01, /* Report Count (269), */ 542d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 543d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 544d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 545d829674dSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 546d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 547d829674dSFrank Praznik 0x96, 0x4D, 0x01, /* Report Count (333), */ 548d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 549d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 550d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 551d829674dSFrank Praznik 0x85, 0x16, /* Report ID (22), */ 552d829674dSFrank Praznik 0x09, 0x2A, /* Usage (2Ah), */ 553d829674dSFrank Praznik 0x96, 0x8D, 0x01, /* Report Count (397), */ 554d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 555d829674dSFrank Praznik 0x09, 0x2B, /* Usage (2Bh), */ 556d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 557d829674dSFrank Praznik 0x85, 0x17, /* Report ID (23), */ 558d829674dSFrank Praznik 0x09, 0x2C, /* Usage (2Ch), */ 559d829674dSFrank Praznik 0x96, 0xCD, 0x01, /* Report Count (461), */ 560d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 561d829674dSFrank Praznik 0x09, 0x2D, /* Usage (2Dh), */ 562d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 563d829674dSFrank Praznik 0x85, 0x18, /* Report ID (24), */ 564d829674dSFrank Praznik 0x09, 0x2E, /* Usage (2Eh), */ 565d829674dSFrank Praznik 0x96, 0x0D, 0x02, /* Report Count (525), */ 566d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 567d829674dSFrank Praznik 0x09, 0x2F, /* Usage (2Fh), */ 568d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 569d829674dSFrank Praznik 0x85, 0x19, /* Report ID (25), */ 570d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 571d829674dSFrank Praznik 0x96, 0x22, 0x02, /* Report Count (546), */ 572d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 573d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 574d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 575d829674dSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 576d829674dSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 577d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 578d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 579d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 580d829674dSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 581d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 582d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 583d829674dSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 584d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 585d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 586d829674dSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 587d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 588d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 589d829674dSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 590d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 591d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 592d829674dSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 593d829674dSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 594d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 595d829674dSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 596d829674dSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 597d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 598d829674dSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 599d829674dSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 600d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 601d829674dSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 602d829674dSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 603d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 604d829674dSFrank Praznik 0xC0 /* End Collection */ 605d829674dSFrank Praznik }; 606d829674dSFrank Praznik 607078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 608078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 609078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 610078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 611078328daSJiri Kosina 612078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 613078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 614078328daSJiri Kosina 615078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 616078328daSJiri Kosina * number but it's not needed for correct operation */ 617078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 618078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 619078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 620078328daSJiri Kosina 621078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 622078328daSJiri Kosina * buttons multiple keypresses are allowed */ 623078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 624078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 625078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 626078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 627078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 628078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 629078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 630078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 631078328daSJiri Kosina 632078328daSJiri Kosina 0xC0, /* MEndCollection */ 633078328daSJiri Kosina 634078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 635078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 636078328daSJiri Kosina 637078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 638078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 639078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 640078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 641078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 642078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 643078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 644078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 645078328daSJiri Kosina 0x80, /* MInput */ 646078328daSJiri Kosina 647078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 648078328daSJiri Kosina * 0xff and 11th is for press indication */ 649078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 650078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 651078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 652078328daSJiri Kosina 653078328daSJiri Kosina /* 12th byte is for battery strength */ 654078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 655078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 656078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 657078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 658078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 659078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 660078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 661078328daSJiri Kosina 662078328daSJiri Kosina 0xC0, /* MEndCollection */ 663078328daSJiri Kosina 664078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 665078328daSJiri Kosina }; 666078328daSJiri Kosina 667078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 668078328daSJiri Kosina [0x01] = KEY_SELECT, 669078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 670078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 671078328daSJiri Kosina [0x04] = BTN_START, 672078328daSJiri Kosina [0x05] = KEY_UP, 673078328daSJiri Kosina [0x06] = KEY_RIGHT, 674078328daSJiri Kosina [0x07] = KEY_DOWN, 675078328daSJiri Kosina [0x08] = KEY_LEFT, 676078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 677078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 678078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 679078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 680078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 681078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 682078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 683078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 684078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 685078328daSJiri Kosina [0x14] = KEY_ENTER, 686078328daSJiri Kosina }; 687078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 688078328daSJiri Kosina [0x00] = KEY_1, 689078328daSJiri Kosina [0x01] = KEY_2, 690078328daSJiri Kosina [0x02] = KEY_3, 691078328daSJiri Kosina [0x03] = KEY_4, 692078328daSJiri Kosina [0x04] = KEY_5, 693078328daSJiri Kosina [0x05] = KEY_6, 694078328daSJiri Kosina [0x06] = KEY_7, 695078328daSJiri Kosina [0x07] = KEY_8, 696078328daSJiri Kosina [0x08] = KEY_9, 697078328daSJiri Kosina [0x09] = KEY_0, 698078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 699078328daSJiri Kosina [0x0f] = KEY_CLEAR, 700078328daSJiri Kosina [0x16] = KEY_EJECTCD, 701078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 702078328daSJiri Kosina [0x28] = KEY_TIME, 703078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 704078328daSJiri Kosina [0x31] = KEY_NEXT, 705078328daSJiri Kosina [0x32] = KEY_PLAY, 706078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 707078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 708078328daSJiri Kosina [0x38] = KEY_STOP, 709078328daSJiri Kosina [0x39] = KEY_PAUSE, 710078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 711078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 712078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 713078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 714078328daSJiri Kosina [0x64] = KEY_AUDIO, 715078328daSJiri Kosina [0x65] = KEY_ANGLE, 716078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 717078328daSJiri Kosina [0x80] = KEY_BLUE, 718078328daSJiri Kosina [0x81] = KEY_RED, 719078328daSJiri Kosina [0x82] = KEY_GREEN, 720078328daSJiri Kosina [0x83] = KEY_YELLOW, 721078328daSJiri Kosina }; 722078328daSJiri Kosina 723f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 724ad142b9eSFrank Praznik /* 725ad142b9eSFrank Praznik * The controller has 4 remote buzzers, each with one LED and 5 726f04d5140SColin Leitner * buttons. 727f04d5140SColin Leitner * 728f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 729f04d5140SColin Leitner * 730f04d5140SColin Leitner * Key Offset 731f04d5140SColin Leitner * ------------------- 732f04d5140SColin Leitner * Buzz 1 733f04d5140SColin Leitner * Blue 5 734f04d5140SColin Leitner * Orange 4 735f04d5140SColin Leitner * Green 3 736f04d5140SColin Leitner * Yellow 2 737f04d5140SColin Leitner * 738f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 739f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 740f04d5140SColin Leitner */ 741f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 742f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 743f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 744f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 745f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 746f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 747f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 748f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 749f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 750f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 751f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 752f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 753f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 754f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 755f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 756f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 757f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 758f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 759f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 760f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 761f04d5140SColin Leitner }; 762f04d5140SColin Leitner 763d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = { 764d902f472SFrank Praznik POWER_SUPPLY_PROP_PRESENT, 765d902f472SFrank Praznik POWER_SUPPLY_PROP_CAPACITY, 766d902f472SFrank Praznik POWER_SUPPLY_PROP_SCOPE, 767d902f472SFrank Praznik POWER_SUPPLY_PROP_STATUS, 768d902f472SFrank Praznik }; 769d902f472SFrank Praznik 77055d3b664SFrank Praznik struct sixaxis_led { 77155d3b664SFrank Praznik __u8 time_enabled; /* the total time the led is active (0xff means forever) */ 77255d3b664SFrank Praznik __u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ 77355d3b664SFrank Praznik __u8 enabled; 77455d3b664SFrank Praznik __u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ 77555d3b664SFrank Praznik __u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ 77655d3b664SFrank Praznik } __packed; 77755d3b664SFrank Praznik 77855d3b664SFrank Praznik struct sixaxis_rumble { 77955d3b664SFrank Praznik __u8 padding; 78055d3b664SFrank Praznik __u8 right_duration; /* Right motor duration (0xff means forever) */ 78155d3b664SFrank Praznik __u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ 78255d3b664SFrank Praznik __u8 left_duration; /* Left motor duration (0xff means forever) */ 78355d3b664SFrank Praznik __u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ 78455d3b664SFrank Praznik } __packed; 78555d3b664SFrank Praznik 78655d3b664SFrank Praznik struct sixaxis_output_report { 78755d3b664SFrank Praznik __u8 report_id; 78855d3b664SFrank Praznik struct sixaxis_rumble rumble; 78955d3b664SFrank Praznik __u8 padding[4]; 79055d3b664SFrank Praznik __u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ 79155d3b664SFrank Praznik struct sixaxis_led led[4]; /* LEDx at (4 - x) */ 79255d3b664SFrank Praznik struct sixaxis_led _reserved; /* LED5, not actually soldered */ 79355d3b664SFrank Praznik } __packed; 79455d3b664SFrank Praznik 79555d3b664SFrank Praznik union sixaxis_output_report_01 { 79655d3b664SFrank Praznik struct sixaxis_output_report data; 79755d3b664SFrank Praznik __u8 buf[36]; 79855d3b664SFrank Praznik }; 79955d3b664SFrank Praznik 800d2d782fcSFrank Praznik static spinlock_t sony_dev_list_lock; 801d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list); 8028025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator); 803d2d782fcSFrank Praznik 804cc6e0bbbSJiri Kosina struct sony_sc { 805d902f472SFrank Praznik spinlock_t lock; 806d2d782fcSFrank Praznik struct list_head list_node; 8070a286ef2SSven Eckelmann struct hid_device *hdev; 80860781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 809cc6e0bbbSJiri Kosina unsigned long quirks; 8100a286ef2SSven Eckelmann struct work_struct state_worker; 811d902f472SFrank Praznik struct power_supply battery; 8128025087aSFrank Praznik int device_id; 813f04d5140SColin Leitner 8149f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 8159f323b68SSven Eckelmann __u8 left; 8169f323b68SSven Eckelmann __u8 right; 8179f323b68SSven Eckelmann #endif 8189f323b68SSven Eckelmann 819d2d782fcSFrank Praznik __u8 mac_address[6]; 8205f5750d2SFrank Praznik __u8 worker_initialized; 821d902f472SFrank Praznik __u8 cable_state; 822d902f472SFrank Praznik __u8 battery_charging; 823d902f472SFrank Praznik __u8 battery_capacity; 82460781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 825b3ed458cSFrank Praznik __u8 led_delay_on[MAX_LEDS]; 826b3ed458cSFrank Praznik __u8 led_delay_off[MAX_LEDS]; 82760781cf4SFrank Praznik __u8 led_count; 828cc6e0bbbSJiri Kosina }; 829cc6e0bbbSJiri Kosina 830c607fb8dSAntonio Ospite static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, 831c607fb8dSAntonio Ospite unsigned int *rsize) 832c607fb8dSAntonio Ospite { 833c607fb8dSAntonio Ospite *rsize = sizeof(sixaxis_rdesc); 834c607fb8dSAntonio Ospite return sixaxis_rdesc; 835c607fb8dSAntonio Ospite } 836c607fb8dSAntonio Ospite 837078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 838078328daSJiri Kosina unsigned int *rsize) 839078328daSJiri Kosina { 840078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 841078328daSJiri Kosina return ps3remote_rdesc; 842078328daSJiri Kosina } 843078328daSJiri Kosina 844078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 845078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 846078328daSJiri Kosina unsigned long **bit, int *max) 847078328daSJiri Kosina { 848078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 849078328daSJiri Kosina 850078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 851078328daSJiri Kosina return -1; 852078328daSJiri Kosina 853078328daSJiri Kosina switch (usage->collection_index) { 854078328daSJiri Kosina case 1: 855078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 856078328daSJiri Kosina return -1; 857078328daSJiri Kosina 858078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 859078328daSJiri Kosina if (!key) 860078328daSJiri Kosina return -1; 861078328daSJiri Kosina break; 862078328daSJiri Kosina case 2: 863078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 864078328daSJiri Kosina return -1; 865078328daSJiri Kosina 866078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 867078328daSJiri Kosina if (!key) 868078328daSJiri Kosina return -1; 869078328daSJiri Kosina break; 870078328daSJiri Kosina default: 871078328daSJiri Kosina return -1; 872078328daSJiri Kosina } 873078328daSJiri Kosina 874078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 875078328daSJiri Kosina return 1; 876078328daSJiri Kosina } 877078328daSJiri Kosina 87873e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 87973e4008dSNikolai Kondrashov unsigned int *rsize) 880cc6e0bbbSJiri Kosina { 881cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 882cc6e0bbbSJiri Kosina 88399d24902SFernando Luis Vázquez Cao /* 88499d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 88599d24902SFernando Luis Vázquez Cao * a constant non-data variable. 88699d24902SFernando Luis Vázquez Cao */ 88799d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 88899d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 88999d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 89099d24902SFernando Luis Vázquez Cao /* usage: mouse */ 89199d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 89299d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 89399d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 894a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 89599d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 896cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 897cc6e0bbbSJiri Kosina } 89861ab44beSSimon Wood 899ed19d8cfSFrank Praznik /* 900ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 901ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 902ed19d8cfSFrank Praznik * modified one. 903ed19d8cfSFrank Praznik */ 904ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 905ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 906ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 907ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 908d829674dSFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { 909d829674dSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); 910d829674dSFrank Praznik rdesc = dualshock4_bt_rdesc; 911d829674dSFrank Praznik *rsize = sizeof(dualshock4_bt_rdesc); 912ed19d8cfSFrank Praznik } 913ed19d8cfSFrank Praznik 914c607fb8dSAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER) 915c607fb8dSAntonio Ospite return sixaxis_fixup(hdev, rdesc, rsize); 916078328daSJiri Kosina 917078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 918078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 919078328daSJiri Kosina 92073e4008dSNikolai Kondrashov return rdesc; 921cc6e0bbbSJiri Kosina } 922cc6e0bbbSJiri Kosina 923d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) 924d902f472SFrank Praznik { 925d902f472SFrank Praznik static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 926d902f472SFrank Praznik unsigned long flags; 927d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 928d902f472SFrank Praznik 929ad142b9eSFrank Praznik /* 930ad142b9eSFrank Praznik * The sixaxis is charging if the battery value is 0xee 931d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 932d902f472SFrank Praznik * It does not report the actual level while charging so it 933d902f472SFrank Praznik * is set to 100% while charging is in progress. 934d902f472SFrank Praznik */ 935d902f472SFrank Praznik if (rd[30] >= 0xee) { 936d902f472SFrank Praznik battery_capacity = 100; 937a43e94a3SFrank Praznik battery_charging = !(rd[30] & 0x01); 9389fddd74aSFrank Praznik cable_state = 1; 939d902f472SFrank Praznik } else { 940ac3c9a94SFrank Praznik __u8 index = rd[30] <= 5 ? rd[30] : 5; 941ac3c9a94SFrank Praznik battery_capacity = sixaxis_battery_capacity[index]; 942d902f472SFrank Praznik battery_charging = 0; 9439fddd74aSFrank Praznik cable_state = 0; 944d902f472SFrank Praznik } 945d902f472SFrank Praznik 946d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 947d902f472SFrank Praznik sc->cable_state = cable_state; 948d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 949d902f472SFrank Praznik sc->battery_charging = battery_charging; 950d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 951d902f472SFrank Praznik } 952d902f472SFrank Praznik 953d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) 954d902f472SFrank Praznik { 955e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 956e5606230SFrank Praznik struct hid_input, list); 957e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 958d902f472SFrank Praznik unsigned long flags; 9596c5f860dSFrank Praznik int n, offset; 960d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 961d902f472SFrank Praznik 962ad142b9eSFrank Praznik /* 963ad142b9eSFrank Praznik * Battery and touchpad data starts at byte 30 in the USB report and 9646c5f860dSFrank Praznik * 32 in Bluetooth report. 9656c5f860dSFrank Praznik */ 9666c5f860dSFrank Praznik offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; 9676c5f860dSFrank Praznik 968ad142b9eSFrank Praznik /* 969ad142b9eSFrank Praznik * The lower 4 bits of byte 30 contain the battery level 970d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 971d902f472SFrank Praznik */ 9726c5f860dSFrank Praznik cable_state = (rd[offset] >> 4) & 0x01; 9736c5f860dSFrank Praznik battery_capacity = rd[offset] & 0x0F; 974d902f472SFrank Praznik 975ad142b9eSFrank Praznik /* 976ad142b9eSFrank Praznik * When a USB power source is connected the battery level ranges from 9776c5f860dSFrank Praznik * 0 to 10, and when running on battery power it ranges from 0 to 9. 9786c5f860dSFrank Praznik * A battery level above 10 when plugged in means charge completed. 979d902f472SFrank Praznik */ 9806c5f860dSFrank Praznik if (!cable_state || battery_capacity > 10) 981d902f472SFrank Praznik battery_charging = 0; 982d902f472SFrank Praznik else 983d902f472SFrank Praznik battery_charging = 1; 984d902f472SFrank Praznik 9856c5f860dSFrank Praznik if (!cable_state) 9866c5f860dSFrank Praznik battery_capacity++; 987d902f472SFrank Praznik if (battery_capacity > 10) 9886c5f860dSFrank Praznik battery_capacity = 10; 9896c5f860dSFrank Praznik 990d902f472SFrank Praznik battery_capacity *= 10; 991d902f472SFrank Praznik 992d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 993d902f472SFrank Praznik sc->cable_state = cable_state; 994d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 995d902f472SFrank Praznik sc->battery_charging = battery_charging; 996d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 997e5606230SFrank Praznik 9986c5f860dSFrank Praznik offset += 5; 9996c5f860dSFrank Praznik 1000ad142b9eSFrank Praznik /* 1001ad142b9eSFrank Praznik * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB 10026c5f860dSFrank Praznik * and 37 on Bluetooth. 1003e5606230SFrank Praznik * The first 7 bits of the first byte is a counter and bit 8 is a touch 1004e5606230SFrank Praznik * indicator that is 0 when pressed and 1 when not pressed. 1005e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 1006e5606230SFrank Praznik * The data for the second touch is in the same format and immediatly 1007e5606230SFrank Praznik * follows the data for the first. 1008e5606230SFrank Praznik */ 1009e5606230SFrank Praznik for (n = 0; n < 2; n++) { 1010e5606230SFrank Praznik __u16 x, y; 1011e5606230SFrank Praznik 1012e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 1013e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 1014e5606230SFrank Praznik 1015e5606230SFrank Praznik input_mt_slot(input_dev, n); 1016e5606230SFrank Praznik input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1017e5606230SFrank Praznik !(rd[offset] >> 7)); 1018e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_X, x); 1019e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 1020e5606230SFrank Praznik 1021e5606230SFrank Praznik offset += 4; 1022e5606230SFrank Praznik } 1023d902f472SFrank Praznik } 1024d902f472SFrank Praznik 1025c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 1026c9e4d877SSimon Wood __u8 *rd, int size) 1027c9e4d877SSimon Wood { 1028c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 1029c9e4d877SSimon Wood 1030ad142b9eSFrank Praznik /* 1031ad142b9eSFrank Praznik * Sixaxis HID report has acclerometers/gyro with MSByte first, this 1032c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 1033c9e4d877SSimon Wood */ 1034fee4e2d5SFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { 1035c9e4d877SSimon Wood swap(rd[41], rd[42]); 1036c9e4d877SSimon Wood swap(rd[43], rd[44]); 1037c9e4d877SSimon Wood swap(rd[45], rd[46]); 1038c9e4d877SSimon Wood swap(rd[47], rd[48]); 1039d902f472SFrank Praznik 1040d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 104168330d83SFrank Praznik } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 104268330d83SFrank Praznik size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) 104368330d83SFrank Praznik && rd[0] == 0x11 && size == 78)) { 1044d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 1045c9e4d877SSimon Wood } 1046c9e4d877SSimon Wood 1047c9e4d877SSimon Wood return 0; 1048c9e4d877SSimon Wood } 1049c9e4d877SSimon Wood 1050f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 1051f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 1052f04d5140SColin Leitner unsigned long **bit, int *max) 1053f04d5140SColin Leitner { 1054f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1055f04d5140SColin Leitner 1056f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 1057f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 1058f04d5140SColin Leitner 1059f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 1060f04d5140SColin Leitner return -1; 1061f04d5140SColin Leitner 1062f04d5140SColin Leitner switch (usage->collection_index) { 1063f04d5140SColin Leitner case 1: 1064f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 1065f04d5140SColin Leitner return -1; 1066f04d5140SColin Leitner 1067f04d5140SColin Leitner key = buzz_keymap[key]; 1068f04d5140SColin Leitner if (!key) 1069f04d5140SColin Leitner return -1; 1070f04d5140SColin Leitner break; 1071f04d5140SColin Leitner default: 1072f04d5140SColin Leitner return -1; 1073f04d5140SColin Leitner } 1074f04d5140SColin Leitner 1075f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 1076f04d5140SColin Leitner return 1; 1077f04d5140SColin Leitner } 1078f04d5140SColin Leitner 1079078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 1080078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 1081078328daSJiri Kosina 10826f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 10836f498018SBenjamin Tissoires return 0; 1084f04d5140SColin Leitner } 1085f04d5140SColin Leitner 10865710fabfSAntonio Ospite /* 1087bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1088bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1089bd28ce00SJiri Slaby * events. 1090bd28ce00SJiri Slaby */ 1091816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1092bd28ce00SJiri Slaby { 1093bd28ce00SJiri Slaby int ret; 1094bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 1095bd28ce00SJiri Slaby 1096bd28ce00SJiri Slaby if (!buf) 1097bd28ce00SJiri Slaby return -ENOMEM; 1098bd28ce00SJiri Slaby 1099cafebc05SBenjamin Tissoires ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1100cafebc05SBenjamin Tissoires HID_REQ_GET_REPORT); 1101f204828aSBenjamin Tissoires 1102bd28ce00SJiri Slaby if (ret < 0) 11034291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 1104bd28ce00SJiri Slaby 1105bd28ce00SJiri Slaby kfree(buf); 1106bd28ce00SJiri Slaby 1107bd28ce00SJiri Slaby return ret; 1108bd28ce00SJiri Slaby } 1109bd28ce00SJiri Slaby 1110816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1111f9ce7c28SBastien Nocera { 1112fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 1113b0dd72aaSBenjamin Tissoires return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), 1114b0dd72aaSBenjamin Tissoires HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 1115f9ce7c28SBastien Nocera } 1116f9ce7c28SBastien Nocera 1117ad142b9eSFrank Praznik /* 1118ad142b9eSFrank Praznik * Requesting feature report 0x02 in Bluetooth mode changes the state of the 111968330d83SFrank Praznik * controller so that it sends full input reports of type 0x11. 112068330d83SFrank Praznik */ 112168330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev) 112268330d83SFrank Praznik { 112368330d83SFrank Praznik __u8 buf[37] = { 0 }; 112468330d83SFrank Praznik 112568330d83SFrank Praznik return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), 112668330d83SFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1127bd28ce00SJiri Slaby } 1128bd28ce00SJiri Slaby 11298025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 11308025087aSFrank Praznik { 11318025087aSFrank Praznik static const __u8 sixaxis_leds[10][4] = { 11328025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x00 }, 11338025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x00 }, 11348025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x00 }, 11358025087aSFrank Praznik { 0x00, 0x00, 0x00, 0x01 }, 11368025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x01 }, 11378025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x01 }, 11388025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x01 }, 11398025087aSFrank Praznik { 0x01, 0x00, 0x01, 0x01 }, 11408025087aSFrank Praznik { 0x00, 0x01, 0x01, 0x01 }, 11418025087aSFrank Praznik { 0x01, 0x01, 0x01, 0x01 } 11428025087aSFrank Praznik }; 11438025087aSFrank Praznik 11448025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0])); 11458025087aSFrank Praznik 11468025087aSFrank Praznik if (id < 0) 11478025087aSFrank Praznik return; 11488025087aSFrank Praznik 11498025087aSFrank Praznik id %= 10; 11508025087aSFrank Praznik memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id])); 11518025087aSFrank Praznik } 11528025087aSFrank Praznik 11538025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 11548025087aSFrank Praznik { 11558025087aSFrank Praznik /* The first 4 color/index entries match what the PS4 assigns */ 11568025087aSFrank Praznik static const __u8 color_code[7][3] = { 11578025087aSFrank Praznik /* Blue */ { 0x00, 0x00, 0x01 }, 11588025087aSFrank Praznik /* Red */ { 0x01, 0x00, 0x00 }, 11598025087aSFrank Praznik /* Green */ { 0x00, 0x01, 0x00 }, 11608025087aSFrank Praznik /* Pink */ { 0x02, 0x00, 0x01 }, 11618025087aSFrank Praznik /* Orange */ { 0x02, 0x01, 0x00 }, 11628025087aSFrank Praznik /* Teal */ { 0x00, 0x01, 0x01 }, 11638025087aSFrank Praznik /* White */ { 0x01, 0x01, 0x01 } 11648025087aSFrank Praznik }; 11658025087aSFrank Praznik 11668025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0])); 11678025087aSFrank Praznik 11688025087aSFrank Praznik if (id < 0) 11698025087aSFrank Praznik return; 11708025087aSFrank Praznik 11718025087aSFrank Praznik id %= 7; 11728025087aSFrank Praznik memcpy(values, color_code[id], sizeof(color_code[id])); 11738025087aSFrank Praznik } 11748025087aSFrank Praznik 117560781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 1176f04d5140SColin Leitner { 1177f04d5140SColin Leitner struct list_head *report_list = 1178f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1179f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1180f04d5140SColin Leitner struct hid_report, list); 1181f04d5140SColin Leitner __s32 *value = report->field[0]->value; 1182f04d5140SColin Leitner 1183f04d5140SColin Leitner value[0] = 0x00; 118460781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 118560781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 118660781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 118760781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 1188f04d5140SColin Leitner value[5] = 0x00; 1189f04d5140SColin Leitner value[6] = 0x00; 1190f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1191f04d5140SColin Leitner } 1192f04d5140SColin Leitner 1193fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count) 11940a286ef2SSven Eckelmann { 119560781cf4SFrank Praznik int n; 11960a286ef2SSven Eckelmann 119760781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 119860781cf4SFrank Praznik 1199fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER && count == 4) { 1200fa57a810SFrank Praznik buzz_set_leds(sc->hdev, leds); 1201fee4e2d5SFrank Praznik } else { 120260781cf4SFrank Praznik for (n = 0; n < count; n++) 1203fa57a810SFrank Praznik sc->led_state[n] = leds[n]; 1204fa57a810SFrank Praznik schedule_work(&sc->state_worker); 12050a286ef2SSven Eckelmann } 12060a286ef2SSven Eckelmann } 12070a286ef2SSven Eckelmann 1208c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1209f04d5140SColin Leitner enum led_brightness value) 1210f04d5140SColin Leitner { 1211f04d5140SColin Leitner struct device *dev = led->dev->parent; 1212f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1213f04d5140SColin Leitner struct sony_sc *drv_data; 1214f04d5140SColin Leitner 1215f04d5140SColin Leitner int n; 1216b3ed458cSFrank Praznik int force_update; 1217f04d5140SColin Leitner 1218f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12192251b85fSSven Eckelmann if (!drv_data) { 1220f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1221f04d5140SColin Leitner return; 1222f04d5140SColin Leitner } 1223f04d5140SColin Leitner 1224b3ed458cSFrank Praznik /* 1225b3ed458cSFrank Praznik * The Sixaxis on USB will override any LED settings sent to it 1226b3ed458cSFrank Praznik * and keep flashing all of the LEDs until the PS button is pressed. 1227b3ed458cSFrank Praznik * Updates, even if redundant, must be always be sent to the 1228b3ed458cSFrank Praznik * controller to avoid having to toggle the state of an LED just to 1229b3ed458cSFrank Praznik * stop the flashing later on. 1230b3ed458cSFrank Praznik */ 1231b3ed458cSFrank Praznik force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB); 1232b3ed458cSFrank Praznik 123360781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1234b3ed458cSFrank Praznik if (led == drv_data->leds[n] && (force_update || 1235b3ed458cSFrank Praznik (value != drv_data->led_state[n] || 1236b3ed458cSFrank Praznik drv_data->led_delay_on[n] || 1237b3ed458cSFrank Praznik drv_data->led_delay_off[n]))) { 1238b3ed458cSFrank Praznik 123960781cf4SFrank Praznik drv_data->led_state[n] = value; 1240b3ed458cSFrank Praznik 1241b3ed458cSFrank Praznik /* Setting the brightness stops the blinking */ 1242b3ed458cSFrank Praznik drv_data->led_delay_on[n] = 0; 1243b3ed458cSFrank Praznik drv_data->led_delay_off[n] = 0; 1244b3ed458cSFrank Praznik 1245fa57a810SFrank Praznik sony_set_leds(drv_data, drv_data->led_state, 1246fa57a810SFrank Praznik drv_data->led_count); 1247f04d5140SColin Leitner break; 1248f04d5140SColin Leitner } 1249f04d5140SColin Leitner } 1250f04d5140SColin Leitner } 1251f04d5140SColin Leitner 1252c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1253f04d5140SColin Leitner { 1254f04d5140SColin Leitner struct device *dev = led->dev->parent; 1255f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1256f04d5140SColin Leitner struct sony_sc *drv_data; 1257f04d5140SColin Leitner 1258f04d5140SColin Leitner int n; 1259f04d5140SColin Leitner 1260f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12612251b85fSSven Eckelmann if (!drv_data) { 1262f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1263f04d5140SColin Leitner return LED_OFF; 1264f04d5140SColin Leitner } 1265f04d5140SColin Leitner 126660781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 12677db7504aSSimon Wood if (led == drv_data->leds[n]) 12687db7504aSSimon Wood return drv_data->led_state[n]; 1269f04d5140SColin Leitner } 1270f04d5140SColin Leitner 12717db7504aSSimon Wood return LED_OFF; 1272f04d5140SColin Leitner } 1273f04d5140SColin Leitner 1274b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, 1275b3ed458cSFrank Praznik unsigned long *delay_off) 1276b3ed458cSFrank Praznik { 1277b3ed458cSFrank Praznik struct device *dev = led->dev->parent; 1278b3ed458cSFrank Praznik struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1279b3ed458cSFrank Praznik struct sony_sc *drv_data = hid_get_drvdata(hdev); 1280b3ed458cSFrank Praznik int n; 1281b3ed458cSFrank Praznik __u8 new_on, new_off; 1282b3ed458cSFrank Praznik 1283b3ed458cSFrank Praznik if (!drv_data) { 1284b3ed458cSFrank Praznik hid_err(hdev, "No device data\n"); 1285b3ed458cSFrank Praznik return -EINVAL; 1286b3ed458cSFrank Praznik } 1287b3ed458cSFrank Praznik 1288b3ed458cSFrank Praznik /* Max delay is 255 deciseconds or 2550 milliseconds */ 1289b3ed458cSFrank Praznik if (*delay_on > 2550) 1290b3ed458cSFrank Praznik *delay_on = 2550; 1291b3ed458cSFrank Praznik if (*delay_off > 2550) 1292b3ed458cSFrank Praznik *delay_off = 2550; 1293b3ed458cSFrank Praznik 1294b3ed458cSFrank Praznik /* Blink at 1 Hz if both values are zero */ 1295b3ed458cSFrank Praznik if (!*delay_on && !*delay_off) 1296b3ed458cSFrank Praznik *delay_on = *delay_off = 500; 1297b3ed458cSFrank Praznik 1298b3ed458cSFrank Praznik new_on = *delay_on / 10; 1299b3ed458cSFrank Praznik new_off = *delay_off / 10; 1300b3ed458cSFrank Praznik 1301b3ed458cSFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1302b3ed458cSFrank Praznik if (led == drv_data->leds[n]) 1303b3ed458cSFrank Praznik break; 1304b3ed458cSFrank Praznik } 1305b3ed458cSFrank Praznik 1306b3ed458cSFrank Praznik /* This LED is not registered on this device */ 1307b3ed458cSFrank Praznik if (n >= drv_data->led_count) 1308b3ed458cSFrank Praznik return -EINVAL; 1309b3ed458cSFrank Praznik 1310b3ed458cSFrank Praznik /* Don't schedule work if the values didn't change */ 1311b3ed458cSFrank Praznik if (new_on != drv_data->led_delay_on[n] || 1312b3ed458cSFrank Praznik new_off != drv_data->led_delay_off[n]) { 1313b3ed458cSFrank Praznik drv_data->led_delay_on[n] = new_on; 1314b3ed458cSFrank Praznik drv_data->led_delay_off[n] = new_off; 1315b3ed458cSFrank Praznik schedule_work(&drv_data->state_worker); 1316b3ed458cSFrank Praznik } 1317b3ed458cSFrank Praznik 1318b3ed458cSFrank Praznik return 0; 1319b3ed458cSFrank Praznik } 1320b3ed458cSFrank Praznik 1321fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc) 13220a286ef2SSven Eckelmann { 13230a286ef2SSven Eckelmann struct led_classdev *led; 13240a286ef2SSven Eckelmann int n; 13250a286ef2SSven Eckelmann 1326fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 13270a286ef2SSven Eckelmann 1328fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 1329fa57a810SFrank Praznik led = sc->leds[n]; 1330fa57a810SFrank Praznik sc->leds[n] = NULL; 13310a286ef2SSven Eckelmann if (!led) 13320a286ef2SSven Eckelmann continue; 13330a286ef2SSven Eckelmann led_classdev_unregister(led); 13340a286ef2SSven Eckelmann kfree(led); 13350a286ef2SSven Eckelmann } 133660781cf4SFrank Praznik 1337fa57a810SFrank Praznik sc->led_count = 0; 13380a286ef2SSven Eckelmann } 13390a286ef2SSven Eckelmann 1340fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc) 1341f04d5140SColin Leitner { 1342fa57a810SFrank Praznik struct hid_device *hdev = sc->hdev; 134340e32ee6SJiri Kosina int n, ret = 0; 1344b3ed458cSFrank Praznik int use_ds4_names; 134540e32ee6SJiri Kosina struct led_classdev *led; 134640e32ee6SJiri Kosina size_t name_sz; 134740e32ee6SJiri Kosina char *name; 13480a286ef2SSven Eckelmann size_t name_len; 13490a286ef2SSven Eckelmann const char *name_fmt; 1350b3ed458cSFrank Praznik static const char * const ds4_name_str[] = { "red", "green", "blue", 1351b3ed458cSFrank Praznik "global" }; 13528025087aSFrank Praznik __u8 initial_values[MAX_LEDS] = { 0 }; 13535607c89aSFrank Praznik __u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 }; 1354b3ed458cSFrank Praznik __u8 use_hw_blink[MAX_LEDS] = { 0 }; 1355f04d5140SColin Leitner 1356fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1357f04d5140SColin Leitner 1358fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER) { 1359fa57a810SFrank Praznik sc->led_count = 4; 1360b3ed458cSFrank Praznik use_ds4_names = 0; 13610a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 13620a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 13639446edb9SKees Cook /* Validate expected report characteristics. */ 13649446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 13659446edb9SKees Cook return -ENODEV; 1366fa57a810SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 13678025087aSFrank Praznik dualshock4_set_leds_from_id(sc->device_id, initial_values); 1368b3ed458cSFrank Praznik initial_values[3] = 1; 1369b3ed458cSFrank Praznik sc->led_count = 4; 1370b3ed458cSFrank Praznik memset(max_brightness, 255, 3); 1371b3ed458cSFrank Praznik use_hw_blink[3] = 1; 1372b3ed458cSFrank Praznik use_ds4_names = 1; 137361ebca93SFrank Praznik name_len = 0; 137461ebca93SFrank Praznik name_fmt = "%s:%s"; 137560781cf4SFrank Praznik } else { 13768025087aSFrank Praznik sixaxis_set_leds_from_id(sc->device_id, initial_values); 1377fa57a810SFrank Praznik sc->led_count = 4; 1378b3ed458cSFrank Praznik memset(use_hw_blink, 1, 4); 1379b3ed458cSFrank Praznik use_ds4_names = 0; 138061ebca93SFrank Praznik name_len = strlen("::sony#"); 138161ebca93SFrank Praznik name_fmt = "%s::sony%d"; 138260781cf4SFrank Praznik } 138360781cf4SFrank Praznik 1384ad142b9eSFrank Praznik /* 1385ad142b9eSFrank Praznik * Clear LEDs as we have no way of reading their initial state. This is 1386f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1387ad142b9eSFrank Praznik * LEDs to on 1388ad142b9eSFrank Praznik */ 1389fa57a810SFrank Praznik sony_set_leds(sc, initial_values, sc->led_count); 1390f04d5140SColin Leitner 13910a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1392f04d5140SColin Leitner 1393fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 139461ebca93SFrank Praznik 1395b3ed458cSFrank Praznik if (use_ds4_names) 1396b3ed458cSFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2; 139761ebca93SFrank Praznik 1398f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1399f04d5140SColin Leitner if (!led) { 1400f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 14018cd5fcdaSJulia Lawall ret = -ENOMEM; 1402f04d5140SColin Leitner goto error_leds; 1403f04d5140SColin Leitner } 1404f04d5140SColin Leitner 1405f04d5140SColin Leitner name = (void *)(&led[1]); 1406b3ed458cSFrank Praznik if (use_ds4_names) 1407b3ed458cSFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), 1408b3ed458cSFrank Praznik ds4_name_str[n]); 140961ebca93SFrank Praznik else 14100a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1411f04d5140SColin Leitner led->name = name; 14128025087aSFrank Praznik led->brightness = initial_values[n]; 1413b3ed458cSFrank Praznik led->max_brightness = max_brightness[n]; 1414c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1415c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1416f04d5140SColin Leitner 1417b3ed458cSFrank Praznik if (use_hw_blink[n]) 1418b3ed458cSFrank Praznik led->blink_set = sony_led_blink_set; 1419b3ed458cSFrank Praznik 14208025087aSFrank Praznik sc->leds[n] = led; 14218025087aSFrank Praznik 14228cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 14238cd5fcdaSJulia Lawall if (ret) { 1424f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 14258025087aSFrank Praznik sc->leds[n] = NULL; 1426f04d5140SColin Leitner kfree(led); 1427f04d5140SColin Leitner goto error_leds; 1428f04d5140SColin Leitner } 1429f04d5140SColin Leitner } 1430f04d5140SColin Leitner 1431f04d5140SColin Leitner return ret; 1432f04d5140SColin Leitner 1433f04d5140SColin Leitner error_leds: 1434fa57a810SFrank Praznik sony_leds_remove(sc); 1435f04d5140SColin Leitner 1436f04d5140SColin Leitner return ret; 1437f04d5140SColin Leitner } 1438f04d5140SColin Leitner 1439cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 1440a08c22c0SSven Eckelmann { 144192b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1442b3ed458cSFrank Praznik int n; 144355d3b664SFrank Praznik union sixaxis_output_report_01 report = { 144455d3b664SFrank Praznik .buf = { 1445a08c22c0SSven Eckelmann 0x01, 1446a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 14470a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1448a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1449a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1450a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1451a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1452a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 145355d3b664SFrank Praznik } 1454a08c22c0SSven Eckelmann }; 14559f323b68SSven Eckelmann 14560a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 145755d3b664SFrank Praznik report.data.rumble.right_motor_on = sc->right ? 1 : 0; 145855d3b664SFrank Praznik report.data.rumble.left_motor_force = sc->left; 14590a286ef2SSven Eckelmann #endif 14600a286ef2SSven Eckelmann 146155d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[0] << 1; 146255d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[1] << 2; 146355d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[2] << 3; 146455d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[3] << 4; 14659f323b68SSven Eckelmann 146688f6576fSSimon Wood /* Set flag for all leds off, required for 3rd party INTEC controller */ 146788f6576fSSimon Wood if ((report.data.leds_bitmap & 0x1E) == 0) 146888f6576fSSimon Wood report.data.leds_bitmap |= 0x20; 146988f6576fSSimon Wood 1470b3ed458cSFrank Praznik /* 1471b3ed458cSFrank Praznik * The LEDs in the report are indexed in reverse order to their 1472b3ed458cSFrank Praznik * corresponding light on the controller. 1473b3ed458cSFrank Praznik * Index 0 = LED 4, index 1 = LED 3, etc... 1474b3ed458cSFrank Praznik * 1475b3ed458cSFrank Praznik * In the case of both delay values being zero (blinking disabled) the 1476b3ed458cSFrank Praznik * default report values should be used or the controller LED will be 1477b3ed458cSFrank Praznik * always off. 1478b3ed458cSFrank Praznik */ 1479b3ed458cSFrank Praznik for (n = 0; n < 4; n++) { 1480b3ed458cSFrank Praznik if (sc->led_delay_on[n] || sc->led_delay_off[n]) { 1481b3ed458cSFrank Praznik report.data.led[3 - n].duty_off = sc->led_delay_off[n]; 1482b3ed458cSFrank Praznik report.data.led[3 - n].duty_on = sc->led_delay_on[n]; 1483b3ed458cSFrank Praznik } 1484b3ed458cSFrank Praznik } 1485b3ed458cSFrank Praznik 148655d3b664SFrank Praznik hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, 148755d3b664SFrank Praznik sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 14889f323b68SSven Eckelmann } 14899f323b68SSven Eckelmann 14900bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 14910bd88dd3SFrank Praznik { 14920bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 14930da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 149448220237SFrank Praznik int offset; 14950da8ea65SFrank Praznik 1496fdcf105dSFrank Praznik __u8 buf[78] = { 0 }; 149748220237SFrank Praznik 1498fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 149948220237SFrank Praznik buf[0] = 0x05; 1500b3ed458cSFrank Praznik buf[1] = 0xFF; 150148220237SFrank Praznik offset = 4; 1502fdcf105dSFrank Praznik } else { 1503fdcf105dSFrank Praznik buf[0] = 0x11; 1504fdcf105dSFrank Praznik buf[1] = 0xB0; 1505fdcf105dSFrank Praznik buf[3] = 0x0F; 1506fdcf105dSFrank Praznik offset = 6; 1507fdcf105dSFrank Praznik } 15080bd88dd3SFrank Praznik 15090bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 151048220237SFrank Praznik buf[offset++] = sc->right; 151148220237SFrank Praznik buf[offset++] = sc->left; 151248220237SFrank Praznik #else 151348220237SFrank Praznik offset += 2; 15140bd88dd3SFrank Praznik #endif 15150bd88dd3SFrank Praznik 1516b3ed458cSFrank Praznik /* LED 3 is the global control */ 1517b3ed458cSFrank Praznik if (sc->led_state[3]) { 151848220237SFrank Praznik buf[offset++] = sc->led_state[0]; 151948220237SFrank Praznik buf[offset++] = sc->led_state[1]; 152048220237SFrank Praznik buf[offset++] = sc->led_state[2]; 1521b3ed458cSFrank Praznik } else { 1522b3ed458cSFrank Praznik offset += 3; 1523b3ed458cSFrank Praznik } 1524b3ed458cSFrank Praznik 1525b3ed458cSFrank Praznik /* If both delay values are zero the DualShock 4 disables blinking. */ 1526b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_on[3]; 1527b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_off[3]; 152860781cf4SFrank Praznik 1529fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1530fdcf105dSFrank Praznik hid_hw_output_report(hdev, buf, 32); 1531fdcf105dSFrank Praznik else 1532fdcf105dSFrank Praznik hid_hw_raw_request(hdev, 0x11, buf, 78, 1533fdcf105dSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 15340bd88dd3SFrank Praznik } 15350bd88dd3SFrank Praznik 15360a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 15379f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 15389f323b68SSven Eckelmann struct ff_effect *effect) 15399f323b68SSven Eckelmann { 1540a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 15419f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 1542a08c22c0SSven Eckelmann 1543a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 1544a08c22c0SSven Eckelmann return 0; 1545a08c22c0SSven Eckelmann 15469f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 15470bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 1548a08c22c0SSven Eckelmann 154992b5c411SSven Eckelmann schedule_work(&sc->state_worker); 15509f323b68SSven Eckelmann return 0; 1551a08c22c0SSven Eckelmann } 1552a08c22c0SSven Eckelmann 1553fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1554a08c22c0SSven Eckelmann { 1555fa57a810SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1556a08c22c0SSven Eckelmann struct hid_input, list); 1557a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 1558a08c22c0SSven Eckelmann 1559a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 1560a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 1561a08c22c0SSven Eckelmann } 1562a08c22c0SSven Eckelmann 1563a08c22c0SSven Eckelmann #else 1564fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1565a08c22c0SSven Eckelmann { 1566a08c22c0SSven Eckelmann return 0; 1567a08c22c0SSven Eckelmann } 15689f323b68SSven Eckelmann 1569a08c22c0SSven Eckelmann #endif 1570a08c22c0SSven Eckelmann 1571d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 1572d902f472SFrank Praznik enum power_supply_property psp, 1573d902f472SFrank Praznik union power_supply_propval *val) 1574c4e1ddf2SFrank Praznik { 1575d902f472SFrank Praznik struct sony_sc *sc = container_of(psy, struct sony_sc, battery); 1576d902f472SFrank Praznik unsigned long flags; 1577d902f472SFrank Praznik int ret = 0; 1578d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 1579c4e1ddf2SFrank Praznik 1580d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 1581d902f472SFrank Praznik battery_charging = sc->battery_charging; 1582d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 1583d902f472SFrank Praznik cable_state = sc->cable_state; 1584d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 1585c4e1ddf2SFrank Praznik 1586d902f472SFrank Praznik switch (psp) { 1587d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 1588d902f472SFrank Praznik val->intval = 1; 1589d902f472SFrank Praznik break; 1590d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 1591d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 1592d902f472SFrank Praznik break; 1593d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 1594d902f472SFrank Praznik val->intval = battery_capacity; 1595d902f472SFrank Praznik break; 1596d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 1597d902f472SFrank Praznik if (battery_charging) 1598d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 1599d902f472SFrank Praznik else 1600d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 1601d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 1602d902f472SFrank Praznik else 1603d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1604d902f472SFrank Praznik break; 1605d902f472SFrank Praznik default: 1606d902f472SFrank Praznik ret = -EINVAL; 1607d902f472SFrank Praznik break; 1608c4e1ddf2SFrank Praznik } 1609d902f472SFrank Praznik return ret; 1610d902f472SFrank Praznik } 1611d902f472SFrank Praznik 1612d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc) 1613d902f472SFrank Praznik { 1614d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 1615d902f472SFrank Praznik int ret; 1616d902f472SFrank Praznik 1617ad142b9eSFrank Praznik /* 1618ad142b9eSFrank Praznik * Set the default battery level to 100% to avoid low battery warnings 1619d9a293a9SFrank Praznik * if the battery is polled before the first device report is received. 1620d9a293a9SFrank Praznik */ 1621d9a293a9SFrank Praznik sc->battery_capacity = 100; 1622d9a293a9SFrank Praznik 1623d902f472SFrank Praznik sc->battery.properties = sony_battery_props; 1624d902f472SFrank Praznik sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); 1625d902f472SFrank Praznik sc->battery.get_property = sony_battery_get_property; 1626d902f472SFrank Praznik sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; 1627d902f472SFrank Praznik sc->battery.use_for_apm = 0; 1628314531f1SFrank Praznik sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR", 1629314531f1SFrank Praznik sc->mac_address); 1630d902f472SFrank Praznik if (!sc->battery.name) 1631d902f472SFrank Praznik return -ENOMEM; 1632d902f472SFrank Praznik 1633d902f472SFrank Praznik ret = power_supply_register(&hdev->dev, &sc->battery); 1634d902f472SFrank Praznik if (ret) { 1635d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 1636d902f472SFrank Praznik goto err_free; 1637d902f472SFrank Praznik } 1638d902f472SFrank Praznik 1639d902f472SFrank Praznik power_supply_powers(&sc->battery, &hdev->dev); 1640d902f472SFrank Praznik return 0; 1641d902f472SFrank Praznik 1642d902f472SFrank Praznik err_free: 1643d902f472SFrank Praznik kfree(sc->battery.name); 1644d902f472SFrank Praznik sc->battery.name = NULL; 1645d902f472SFrank Praznik return ret; 1646d902f472SFrank Praznik } 1647d902f472SFrank Praznik 1648d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 1649d902f472SFrank Praznik { 1650d902f472SFrank Praznik if (!sc->battery.name) 1651d902f472SFrank Praznik return; 1652d902f472SFrank Praznik 1653d902f472SFrank Praznik power_supply_unregister(&sc->battery); 1654d902f472SFrank Praznik kfree(sc->battery.name); 1655d902f472SFrank Praznik sc->battery.name = NULL; 1656d902f472SFrank Praznik } 1657d902f472SFrank Praznik 1658e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1659e5606230SFrank Praznik int w, int h) 1660e5606230SFrank Praznik { 1661e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1662e5606230SFrank Praznik struct hid_input, list); 1663e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 1664e5606230SFrank Praznik int ret; 1665e5606230SFrank Praznik 1666e5606230SFrank Praznik ret = input_mt_init_slots(input_dev, touch_count, 0); 1667e5606230SFrank Praznik if (ret < 0) { 1668e5606230SFrank Praznik hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); 1669e5606230SFrank Praznik return ret; 1670e5606230SFrank Praznik } 1671e5606230SFrank Praznik 1672e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); 1673e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); 1674e5606230SFrank Praznik 1675c4e1ddf2SFrank Praznik return 0; 1676c4e1ddf2SFrank Praznik } 1677e5606230SFrank Praznik 1678d2d782fcSFrank Praznik /* 1679d2d782fcSFrank Praznik * If a controller is plugged in via USB while already connected via Bluetooth 1680d2d782fcSFrank Praznik * it will show up as two devices. A global list of connected controllers and 1681d2d782fcSFrank Praznik * their MAC addresses is maintained to ensure that a device is only connected 1682d2d782fcSFrank Praznik * once. 1683d2d782fcSFrank Praznik */ 1684d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc) 1685d2d782fcSFrank Praznik { 1686d2d782fcSFrank Praznik struct sony_sc *entry; 1687d2d782fcSFrank Praznik unsigned long flags; 1688d2d782fcSFrank Praznik int ret; 1689d2d782fcSFrank Praznik 1690d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1691d2d782fcSFrank Praznik 1692d2d782fcSFrank Praznik list_for_each_entry(entry, &sony_device_list, list_node) { 1693d2d782fcSFrank Praznik ret = memcmp(sc->mac_address, entry->mac_address, 1694d2d782fcSFrank Praznik sizeof(sc->mac_address)); 1695d2d782fcSFrank Praznik if (!ret) { 1696d2d782fcSFrank Praznik ret = -EEXIST; 1697d2d782fcSFrank Praznik hid_info(sc->hdev, "controller with MAC address %pMR already connected\n", 1698d2d782fcSFrank Praznik sc->mac_address); 1699d2d782fcSFrank Praznik goto unlock; 1700d2d782fcSFrank Praznik } 1701c4e1ddf2SFrank Praznik } 1702c4e1ddf2SFrank Praznik 1703d2d782fcSFrank Praznik ret = 0; 1704d2d782fcSFrank Praznik list_add(&(sc->list_node), &sony_device_list); 1705c4e1ddf2SFrank Praznik 1706d2d782fcSFrank Praznik unlock: 1707d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1708d2d782fcSFrank Praznik return ret; 1709d2d782fcSFrank Praznik } 1710d2d782fcSFrank Praznik 1711d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc) 1712d2d782fcSFrank Praznik { 1713d2d782fcSFrank Praznik unsigned long flags; 1714d2d782fcSFrank Praznik 1715d2d782fcSFrank Praznik if (sc->list_node.next) { 1716d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1717d2d782fcSFrank Praznik list_del(&(sc->list_node)); 1718d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1719d2d782fcSFrank Praznik } 1720d2d782fcSFrank Praznik } 1721d2d782fcSFrank Praznik 1722d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc) 1723d2d782fcSFrank Praznik { 1724d2d782fcSFrank Praznik int ret; 1725d2d782fcSFrank Praznik 1726d2d782fcSFrank Praznik /* HIDP stores the device MAC address as a string in the uniq field. */ 1727d2d782fcSFrank Praznik ret = strlen(sc->hdev->uniq); 1728d2d782fcSFrank Praznik if (ret != 17) 1729c4e1ddf2SFrank Praznik return -EINVAL; 1730d2d782fcSFrank Praznik 1731d2d782fcSFrank Praznik ret = sscanf(sc->hdev->uniq, 1732d2d782fcSFrank Praznik "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 1733d2d782fcSFrank Praznik &sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3], 1734d2d782fcSFrank Praznik &sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]); 1735d2d782fcSFrank Praznik 1736d2d782fcSFrank Praznik if (ret != 6) 1737d2d782fcSFrank Praznik return -EINVAL; 1738d2d782fcSFrank Praznik 1739d2d782fcSFrank Praznik return 0; 1740c4e1ddf2SFrank Praznik } 1741c4e1ddf2SFrank Praznik 1742d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc) 1743d2d782fcSFrank Praznik { 1744d2d782fcSFrank Praznik int n, ret; 1745d2d782fcSFrank Praznik 1746d2d782fcSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || 1747d2d782fcSFrank Praznik (sc->quirks & SIXAXIS_CONTROLLER_BT)) { 1748d2d782fcSFrank Praznik /* 1749d2d782fcSFrank Praznik * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC 1750d2d782fcSFrank Praznik * address from the uniq string where HIDP stores it. 1751d2d782fcSFrank Praznik * As uniq cannot be guaranteed to be a MAC address in all cases 1752d2d782fcSFrank Praznik * a failure of this function should not prevent the connection. 1753d2d782fcSFrank Praznik */ 1754d2d782fcSFrank Praznik if (sony_get_bt_devaddr(sc) < 0) { 1755d2d782fcSFrank Praznik hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); 1756d2d782fcSFrank Praznik return 0; 1757d2d782fcSFrank Praznik } 1758d2d782fcSFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1759d2d782fcSFrank Praznik __u8 buf[7]; 1760d2d782fcSFrank Praznik 1761d2d782fcSFrank Praznik /* 1762d2d782fcSFrank Praznik * The MAC address of a DS4 controller connected via USB can be 1763d2d782fcSFrank Praznik * retrieved with feature report 0x81. The address begins at 1764d2d782fcSFrank Praznik * offset 1. 1765d2d782fcSFrank Praznik */ 1766d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf), 1767d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1768d2d782fcSFrank Praznik 1769d2d782fcSFrank Praznik if (ret != 7) { 1770d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); 1771d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1772d2d782fcSFrank Praznik } 1773d2d782fcSFrank Praznik 1774d2d782fcSFrank Praznik memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); 1775d2d782fcSFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1776d2d782fcSFrank Praznik __u8 buf[18]; 1777d2d782fcSFrank Praznik 1778d2d782fcSFrank Praznik /* 1779d2d782fcSFrank Praznik * The MAC address of a Sixaxis controller connected via USB can 1780d2d782fcSFrank Praznik * be retrieved with feature report 0xf2. The address begins at 1781d2d782fcSFrank Praznik * offset 4. 1782d2d782fcSFrank Praznik */ 1783d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf), 1784d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1785d2d782fcSFrank Praznik 1786d2d782fcSFrank Praznik if (ret != 18) { 1787d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); 1788d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1789d2d782fcSFrank Praznik } 1790d2d782fcSFrank Praznik 1791d2d782fcSFrank Praznik /* 1792d2d782fcSFrank Praznik * The Sixaxis device MAC in the report is big-endian and must 1793d2d782fcSFrank Praznik * be byte-swapped. 1794d2d782fcSFrank Praznik */ 1795d2d782fcSFrank Praznik for (n = 0; n < 6; n++) 1796d2d782fcSFrank Praznik sc->mac_address[5-n] = buf[4+n]; 1797d2d782fcSFrank Praznik } else { 1798d2d782fcSFrank Praznik return 0; 1799d2d782fcSFrank Praznik } 1800d2d782fcSFrank Praznik 1801d2d782fcSFrank Praznik return sony_check_add_dev_list(sc); 1802d2d782fcSFrank Praznik } 1803d2d782fcSFrank Praznik 18048025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc) 18058025087aSFrank Praznik { 18068025087aSFrank Praznik int ret; 18078025087aSFrank Praznik 18088025087aSFrank Praznik /* 18098025087aSFrank Praznik * Only DualShock 4 or Sixaxis controllers get an id. 18108025087aSFrank Praznik * All others are set to -1. 18118025087aSFrank Praznik */ 18128025087aSFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) || 18138025087aSFrank Praznik (sc->quirks & DUALSHOCK4_CONTROLLER)) { 18148025087aSFrank Praznik ret = ida_simple_get(&sony_device_id_allocator, 0, 0, 18158025087aSFrank Praznik GFP_KERNEL); 18168025087aSFrank Praznik if (ret < 0) { 18178025087aSFrank Praznik sc->device_id = -1; 18188025087aSFrank Praznik return ret; 18198025087aSFrank Praznik } 18208025087aSFrank Praznik sc->device_id = ret; 18218025087aSFrank Praznik } else { 18228025087aSFrank Praznik sc->device_id = -1; 18238025087aSFrank Praznik } 18248025087aSFrank Praznik 18258025087aSFrank Praznik return 0; 18268025087aSFrank Praznik } 18278025087aSFrank Praznik 18288025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc) 18298025087aSFrank Praznik { 18308025087aSFrank Praznik if (sc->device_id >= 0) { 18318025087aSFrank Praznik ida_simple_remove(&sony_device_id_allocator, sc->device_id); 18328025087aSFrank Praznik sc->device_id = -1; 18338025087aSFrank Praznik } 18348025087aSFrank Praznik } 18358025087aSFrank Praznik 183646262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc, 183746262047SFrank Praznik void (*worker)(struct work_struct *)) 183846262047SFrank Praznik { 183946262047SFrank Praznik if (!sc->worker_initialized) 184046262047SFrank Praznik INIT_WORK(&sc->state_worker, worker); 184146262047SFrank Praznik 184246262047SFrank Praznik sc->worker_initialized = 1; 184346262047SFrank Praznik } 184446262047SFrank Praznik 184546262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc) 184646262047SFrank Praznik { 184746262047SFrank Praznik if (sc->worker_initialized) 184846262047SFrank Praznik cancel_work_sync(&sc->state_worker); 184946262047SFrank Praznik } 1850d2d782fcSFrank Praznik 1851bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1852bd28ce00SJiri Slaby { 1853bd28ce00SJiri Slaby int ret; 1854cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1855cc6e0bbbSJiri Kosina struct sony_sc *sc; 1856f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1857cc6e0bbbSJiri Kosina 1858abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1859cc6e0bbbSJiri Kosina if (sc == NULL) { 18604291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1861cc6e0bbbSJiri Kosina return -ENOMEM; 1862cc6e0bbbSJiri Kosina } 1863cc6e0bbbSJiri Kosina 1864cc6e0bbbSJiri Kosina sc->quirks = quirks; 1865cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 18660a286ef2SSven Eckelmann sc->hdev = hdev; 1867bd28ce00SJiri Slaby 1868bd28ce00SJiri Slaby ret = hid_parse(hdev); 1869bd28ce00SJiri Slaby if (ret) { 18704291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1871abf832bfSBenjamin Tissoires return ret; 1872bd28ce00SJiri Slaby } 1873bd28ce00SJiri Slaby 1874f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1875f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 187650764650SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER) 1877f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1878f04d5140SColin Leitner 1879f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1880bd28ce00SJiri Slaby if (ret) { 18814291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1882abf832bfSBenjamin Tissoires return ret; 1883bd28ce00SJiri Slaby } 1884bd28ce00SJiri Slaby 18858025087aSFrank Praznik ret = sony_set_device_id(sc); 18868025087aSFrank Praznik if (ret < 0) { 18878025087aSFrank Praznik hid_err(hdev, "failed to allocate the device id\n"); 18888025087aSFrank Praznik goto err_stop; 18898025087aSFrank Praznik } 18908025087aSFrank Praznik 1891569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1892e534a935SBenjamin Tissoires /* 1893e534a935SBenjamin Tissoires * The Sony Sixaxis does not handle HID Output Reports on the 1894e534a935SBenjamin Tissoires * Interrupt EP like it could, so we need to force HID Output 1895e534a935SBenjamin Tissoires * Reports to use HID_REQ_SET_REPORT on the Control EP. 1896e534a935SBenjamin Tissoires * 1897e534a935SBenjamin Tissoires * There is also another issue about HID Output Reports via USB, 1898e534a935SBenjamin Tissoires * the Sixaxis does not want the report_id as part of the data 1899e534a935SBenjamin Tissoires * packet, so we have to discard buf[0] when sending the actual 1900e534a935SBenjamin Tissoires * control message, even for numbered reports, humpf! 1901e534a935SBenjamin Tissoires */ 1902e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1903e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; 1904816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 190546262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1906fee4e2d5SFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) { 19072078b9bbSFrank Praznik /* 19082078b9bbSFrank Praznik * The Sixaxis wants output reports sent on the ctrl endpoint 19092078b9bbSFrank Praznik * when connected via Bluetooth. 19102078b9bbSFrank Praznik */ 19112078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1912816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 191346262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1914fee4e2d5SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 191568330d83SFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { 19162078b9bbSFrank Praznik /* 19172078b9bbSFrank Praznik * The DualShock 4 wants output reports sent on the ctrl 19182078b9bbSFrank Praznik * endpoint when connected via Bluetooth. 19192078b9bbSFrank Praznik */ 19202078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 192168330d83SFrank Praznik ret = dualshock4_set_operational_bt(hdev); 192268330d83SFrank Praznik if (ret < 0) { 192368330d83SFrank Praznik hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); 192468330d83SFrank Praznik goto err_stop; 192568330d83SFrank Praznik } 192668330d83SFrank Praznik } 1927ad142b9eSFrank Praznik /* 1928ad142b9eSFrank Praznik * The Dualshock 4 touchpad supports 2 touches and has a 1929e5606230SFrank Praznik * resolution of 1920x940. 1930e5606230SFrank Praznik */ 1931e5606230SFrank Praznik ret = sony_register_touchpad(sc, 2, 1920, 940); 1932c4e1ddf2SFrank Praznik if (ret < 0) 1933c4e1ddf2SFrank Praznik goto err_stop; 1934c4e1ddf2SFrank Praznik 193546262047SFrank Praznik sony_init_work(sc, dualshock4_state_worker); 19360bd88dd3SFrank Praznik } else { 19370bd88dd3SFrank Praznik ret = 0; 19380bd88dd3SFrank Praznik } 1939f9ce7c28SBastien Nocera 19404dfdc464SJiri Kosina if (ret < 0) 1941bd28ce00SJiri Slaby goto err_stop; 1942bd28ce00SJiri Slaby 1943d2d782fcSFrank Praznik ret = sony_check_add(sc); 1944d2d782fcSFrank Praznik if (ret < 0) 1945d2d782fcSFrank Praznik goto err_stop; 1946d2d782fcSFrank Praznik 19470a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 1948fa57a810SFrank Praznik ret = sony_leds_init(sc); 19490a286ef2SSven Eckelmann if (ret < 0) 19500a286ef2SSven Eckelmann goto err_stop; 19510a286ef2SSven Eckelmann } 19520a286ef2SSven Eckelmann 1953d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1954d902f472SFrank Praznik ret = sony_battery_probe(sc); 1955a08c22c0SSven Eckelmann if (ret < 0) 1956a08c22c0SSven Eckelmann goto err_stop; 1957a08c22c0SSven Eckelmann 1958d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 1959d902f472SFrank Praznik ret = hid_hw_open(hdev); 1960d902f472SFrank Praznik if (ret < 0) { 1961d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 1962d902f472SFrank Praznik goto err_stop; 1963d902f472SFrank Praznik } 1964d902f472SFrank Praznik } 1965d902f472SFrank Praznik 1966c8de9dbbSFrank Praznik if (sc->quirks & SONY_FF_SUPPORT) { 1967fa57a810SFrank Praznik ret = sony_init_ff(sc); 1968d902f472SFrank Praznik if (ret < 0) 1969d902f472SFrank Praznik goto err_close; 19705f5750d2SFrank Praznik } 1971bd28ce00SJiri Slaby 1972f425458eSH Hartley Sweeten return 0; 1973d902f472SFrank Praznik err_close: 1974d902f472SFrank Praznik hid_hw_close(hdev); 1975bd28ce00SJiri Slaby err_stop: 19760a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1977fa57a810SFrank Praznik sony_leds_remove(sc); 1978d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 1979d902f472SFrank Praznik sony_battery_remove(sc); 198046262047SFrank Praznik sony_cancel_work_sync(sc); 1981d2d782fcSFrank Praznik sony_remove_dev_list(sc); 19828025087aSFrank Praznik sony_release_device_id(sc); 1983bd28ce00SJiri Slaby hid_hw_stop(hdev); 1984bd28ce00SJiri Slaby return ret; 1985bd28ce00SJiri Slaby } 1986bd28ce00SJiri Slaby 1987bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev) 1988bd28ce00SJiri Slaby { 1989bd28ce00SJiri Slaby struct sony_sc *sc = hid_get_drvdata(hdev); 1990bd28ce00SJiri Slaby 19910a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1992fa57a810SFrank Praznik sony_leds_remove(sc); 1993bd28ce00SJiri Slaby 1994d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1995d902f472SFrank Praznik hid_hw_close(hdev); 1996d902f472SFrank Praznik sony_battery_remove(sc); 1997d902f472SFrank Praznik } 1998d902f472SFrank Praznik 199946262047SFrank Praznik sony_cancel_work_sync(sc); 20009f323b68SSven Eckelmann 2001d2d782fcSFrank Praznik sony_remove_dev_list(sc); 2002bd28ce00SJiri Slaby 20038025087aSFrank Praznik sony_release_device_id(sc); 20048025087aSFrank Praznik 2005bd28ce00SJiri Slaby hid_hw_stop(hdev); 2006bd28ce00SJiri Slaby } 2007bd28ce00SJiri Slaby 2008bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 2009bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2010bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 2011bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 2012bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 2013bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2014bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_BT }, 2015bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 2016bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2017bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 2018bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2019bd28ce00SJiri Slaby /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 2020bd28ce00SJiri Slaby * Logitech joystick from the device descriptor. */ 2021bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 2022bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2023bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 2024bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2025bd28ce00SJiri Slaby /* PS3 BD Remote Control */ 2026bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 2027bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 2028bd28ce00SJiri Slaby /* Logitech Harmony Adapter for PS3 */ 2029bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 2030bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 20310bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 20320bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 20338ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 20340bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 20358ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 2036bd28ce00SJiri Slaby { } 2037bd28ce00SJiri Slaby }; 2038bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 2039bd28ce00SJiri Slaby 2040bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 2041bd28ce00SJiri Slaby .name = "sony", 2042bd28ce00SJiri Slaby .id_table = sony_devices, 2043bd28ce00SJiri Slaby .input_mapping = sony_mapping, 2044bd28ce00SJiri Slaby .probe = sony_probe, 2045bd28ce00SJiri Slaby .remove = sony_remove, 2046bd28ce00SJiri Slaby .report_fixup = sony_report_fixup, 2047bd28ce00SJiri Slaby .raw_event = sony_raw_event 2048bd28ce00SJiri Slaby }; 20498025087aSFrank Praznik 20508025087aSFrank Praznik static int __init sony_init(void) 20518025087aSFrank Praznik { 20528025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20538025087aSFrank Praznik 20548025087aSFrank Praznik return hid_register_driver(&sony_driver); 20558025087aSFrank Praznik } 20568025087aSFrank Praznik 20578025087aSFrank Praznik static void __exit sony_exit(void) 20588025087aSFrank Praznik { 20598025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20608025087aSFrank Praznik 20618025087aSFrank Praznik ida_destroy(&sony_device_id_allocator); 20628025087aSFrank Praznik hid_unregister_driver(&sony_driver); 20638025087aSFrank Praznik } 20648025087aSFrank Praznik module_init(sony_init); 20658025087aSFrank Praznik module_exit(sony_exit); 2066bd28ce00SJiri Slaby 2067bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 2068