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[] = { 60*fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 61*fb705a6dSAntonio Ospite 0x09, 0x04, /* Usage (Joystik), */ 62*fb705a6dSAntonio Ospite 0xA1, 0x01, /* Collection (Application), */ 63*fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 64*fb705a6dSAntonio Ospite 0x85, 0x01, /* Report ID (1), */ 65*fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 66*fb705a6dSAntonio Ospite 0x95, 0x01, /* Report Count (1), */ 67*fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 68*fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 69*fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 70*fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 71*fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 72*fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 73*fb705a6dSAntonio Ospite 0x25, 0x01, /* Logical Maximum (1), */ 74*fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 75*fb705a6dSAntonio Ospite 0x45, 0x01, /* Physical Maximum (1), */ 76*fb705a6dSAntonio Ospite 0x05, 0x09, /* Usage Page (Button), */ 77*fb705a6dSAntonio Ospite 0x19, 0x01, /* Usage Minimum (01h), */ 78*fb705a6dSAntonio Ospite 0x29, 0x13, /* Usage Maximum (13h), */ 79*fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 80*fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 81*fb705a6dSAntonio Ospite 0x95, 0x0D, /* Report Count (13), */ 82*fb705a6dSAntonio Ospite 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 83*fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 84*fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 85*fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 86*fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 87*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 88*fb705a6dSAntonio Ospite 0xA1, 0x00, /* Collection (Physical), */ 89*fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 90*fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 91*fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 92*fb705a6dSAntonio Ospite 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 93*fb705a6dSAntonio Ospite 0x09, 0x30, /* Usage (X), */ 94*fb705a6dSAntonio Ospite 0x09, 0x31, /* Usage (Y), */ 95*fb705a6dSAntonio Ospite 0x09, 0x32, /* Usage (Z), */ 96*fb705a6dSAntonio Ospite 0x09, 0x35, /* Usage (Rz), */ 97*fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 98*fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 99*fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 100*fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 101*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 102*fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 103*fb705a6dSAntonio Ospite 0x95, 0x0C, /* Report Count (12), */ 104*fb705a6dSAntonio Ospite 0x81, 0x01, /* Input (Constant), */ 105*fb705a6dSAntonio Ospite 0x75, 0x10, /* Report Size (16), */ 106*fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 107*fb705a6dSAntonio Ospite 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 108*fb705a6dSAntonio Ospite 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ 109*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 110*fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 111*fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 112*fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 113*fb705a6dSAntonio Ospite 0x85, 0x02, /* Report ID (2), */ 114*fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 115*fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 116*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 117*fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 118*fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 119*fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 120*fb705a6dSAntonio Ospite 0x85, 0xEE, /* Report ID (238), */ 121*fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 122*fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 123*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 124*fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 125*fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 126*fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 127*fb705a6dSAntonio Ospite 0x85, 0xEF, /* Report ID (239), */ 128*fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 129*fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 130*fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 131*fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 132*fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 133*fb705a6dSAntonio 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), */ 17958d7027bSFrank Praznik 0x25, 0x7F, /* Logical Maximum (127), */ 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), */ 20358d7027bSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 20458d7027bSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 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), */ 21058d7027bSFrank Praznik 0x25, 0xFF, /* 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), */ 512d829674dSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 513d829674dSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 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 878078328daSJiri Kosina 879cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 88073e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 88173e4008dSNikolai Kondrashov unsigned int *rsize) 882cc6e0bbbSJiri Kosina { 883cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 884cc6e0bbbSJiri Kosina 88599d24902SFernando Luis Vázquez Cao /* 88699d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 88799d24902SFernando Luis Vázquez Cao * a constant non-data variable. 88899d24902SFernando Luis Vázquez Cao */ 88999d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 89099d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 89199d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 89299d24902SFernando Luis Vázquez Cao /* usage: mouse */ 89399d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 89499d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 89599d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 896a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 89799d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 898cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 899cc6e0bbbSJiri Kosina } 90061ab44beSSimon Wood 901ed19d8cfSFrank Praznik /* 902ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 903ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 904ed19d8cfSFrank Praznik * modified one. 905ed19d8cfSFrank Praznik */ 906ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 907ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 908ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 909ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 910d829674dSFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { 911d829674dSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); 912d829674dSFrank Praznik rdesc = dualshock4_bt_rdesc; 913d829674dSFrank Praznik *rsize = sizeof(dualshock4_bt_rdesc); 914ed19d8cfSFrank Praznik } 915ed19d8cfSFrank Praznik 916c607fb8dSAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER) 917c607fb8dSAntonio Ospite return sixaxis_fixup(hdev, rdesc, rsize); 918078328daSJiri Kosina 919078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 920078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 921078328daSJiri Kosina 92273e4008dSNikolai Kondrashov return rdesc; 923cc6e0bbbSJiri Kosina } 924cc6e0bbbSJiri Kosina 925d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) 926d902f472SFrank Praznik { 927d902f472SFrank Praznik static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 928d902f472SFrank Praznik unsigned long flags; 929d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 930d902f472SFrank Praznik 931ad142b9eSFrank Praznik /* 932ad142b9eSFrank Praznik * The sixaxis is charging if the battery value is 0xee 933d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 934d902f472SFrank Praznik * It does not report the actual level while charging so it 935d902f472SFrank Praznik * is set to 100% while charging is in progress. 936d902f472SFrank Praznik */ 937d902f472SFrank Praznik if (rd[30] >= 0xee) { 938d902f472SFrank Praznik battery_capacity = 100; 939a43e94a3SFrank Praznik battery_charging = !(rd[30] & 0x01); 940d902f472SFrank Praznik } else { 941ac3c9a94SFrank Praznik __u8 index = rd[30] <= 5 ? rd[30] : 5; 942ac3c9a94SFrank Praznik battery_capacity = sixaxis_battery_capacity[index]; 943d902f472SFrank Praznik battery_charging = 0; 944d902f472SFrank Praznik } 945914c5783SFrank Praznik cable_state = !(rd[31] & 0x04); 946d902f472SFrank Praznik 947d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 948d902f472SFrank Praznik sc->cable_state = cable_state; 949d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 950d902f472SFrank Praznik sc->battery_charging = battery_charging; 951d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 952d902f472SFrank Praznik } 953d902f472SFrank Praznik 954d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) 955d902f472SFrank Praznik { 956e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 957e5606230SFrank Praznik struct hid_input, list); 958e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 959d902f472SFrank Praznik unsigned long flags; 9606c5f860dSFrank Praznik int n, offset; 961d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 962d902f472SFrank Praznik 963ad142b9eSFrank Praznik /* 964ad142b9eSFrank Praznik * Battery and touchpad data starts at byte 30 in the USB report and 9656c5f860dSFrank Praznik * 32 in Bluetooth report. 9666c5f860dSFrank Praznik */ 9676c5f860dSFrank Praznik offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; 9686c5f860dSFrank Praznik 969ad142b9eSFrank Praznik /* 970ad142b9eSFrank Praznik * The lower 4 bits of byte 30 contain the battery level 971d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 972d902f472SFrank Praznik */ 9736c5f860dSFrank Praznik cable_state = (rd[offset] >> 4) & 0x01; 9746c5f860dSFrank Praznik battery_capacity = rd[offset] & 0x0F; 975d902f472SFrank Praznik 976ad142b9eSFrank Praznik /* 977ad142b9eSFrank Praznik * When a USB power source is connected the battery level ranges from 9786c5f860dSFrank Praznik * 0 to 10, and when running on battery power it ranges from 0 to 9. 9796c5f860dSFrank Praznik * A battery level above 10 when plugged in means charge completed. 980d902f472SFrank Praznik */ 9816c5f860dSFrank Praznik if (!cable_state || battery_capacity > 10) 982d902f472SFrank Praznik battery_charging = 0; 983d902f472SFrank Praznik else 984d902f472SFrank Praznik battery_charging = 1; 985d902f472SFrank Praznik 9866c5f860dSFrank Praznik if (!cable_state) 9876c5f860dSFrank Praznik battery_capacity++; 988d902f472SFrank Praznik if (battery_capacity > 10) 9896c5f860dSFrank Praznik battery_capacity = 10; 9906c5f860dSFrank Praznik 991d902f472SFrank Praznik battery_capacity *= 10; 992d902f472SFrank Praznik 993d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 994d902f472SFrank Praznik sc->cable_state = cable_state; 995d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 996d902f472SFrank Praznik sc->battery_charging = battery_charging; 997d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 998e5606230SFrank Praznik 9996c5f860dSFrank Praznik offset += 5; 10006c5f860dSFrank Praznik 1001ad142b9eSFrank Praznik /* 1002ad142b9eSFrank Praznik * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB 10036c5f860dSFrank Praznik * and 37 on Bluetooth. 1004e5606230SFrank Praznik * The first 7 bits of the first byte is a counter and bit 8 is a touch 1005e5606230SFrank Praznik * indicator that is 0 when pressed and 1 when not pressed. 1006e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 1007e5606230SFrank Praznik * The data for the second touch is in the same format and immediatly 1008e5606230SFrank Praznik * follows the data for the first. 1009e5606230SFrank Praznik */ 1010e5606230SFrank Praznik for (n = 0; n < 2; n++) { 1011e5606230SFrank Praznik __u16 x, y; 1012e5606230SFrank Praznik 1013e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 1014e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 1015e5606230SFrank Praznik 1016e5606230SFrank Praznik input_mt_slot(input_dev, n); 1017e5606230SFrank Praznik input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1018e5606230SFrank Praznik !(rd[offset] >> 7)); 1019e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_X, x); 1020e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 1021e5606230SFrank Praznik 1022e5606230SFrank Praznik offset += 4; 1023e5606230SFrank Praznik } 1024d902f472SFrank Praznik } 1025d902f472SFrank Praznik 1026c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 1027c9e4d877SSimon Wood __u8 *rd, int size) 1028c9e4d877SSimon Wood { 1029c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 1030c9e4d877SSimon Wood 1031ad142b9eSFrank Praznik /* 1032ad142b9eSFrank Praznik * Sixaxis HID report has acclerometers/gyro with MSByte first, this 1033c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 1034c9e4d877SSimon Wood */ 1035fee4e2d5SFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { 1036c9e4d877SSimon Wood swap(rd[41], rd[42]); 1037c9e4d877SSimon Wood swap(rd[43], rd[44]); 1038c9e4d877SSimon Wood swap(rd[45], rd[46]); 1039c9e4d877SSimon Wood swap(rd[47], rd[48]); 1040d902f472SFrank Praznik 1041d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 104268330d83SFrank Praznik } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 104368330d83SFrank Praznik size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) 104468330d83SFrank Praznik && rd[0] == 0x11 && size == 78)) { 1045d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 1046c9e4d877SSimon Wood } 1047c9e4d877SSimon Wood 1048c9e4d877SSimon Wood return 0; 1049c9e4d877SSimon Wood } 1050c9e4d877SSimon Wood 1051f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 1052f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 1053f04d5140SColin Leitner unsigned long **bit, int *max) 1054f04d5140SColin Leitner { 1055f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1056f04d5140SColin Leitner 1057f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 1058f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 1059f04d5140SColin Leitner 1060f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 1061f04d5140SColin Leitner return -1; 1062f04d5140SColin Leitner 1063f04d5140SColin Leitner switch (usage->collection_index) { 1064f04d5140SColin Leitner case 1: 1065f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 1066f04d5140SColin Leitner return -1; 1067f04d5140SColin Leitner 1068f04d5140SColin Leitner key = buzz_keymap[key]; 1069f04d5140SColin Leitner if (!key) 1070f04d5140SColin Leitner return -1; 1071f04d5140SColin Leitner break; 1072f04d5140SColin Leitner default: 1073f04d5140SColin Leitner return -1; 1074f04d5140SColin Leitner } 1075f04d5140SColin Leitner 1076f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 1077f04d5140SColin Leitner return 1; 1078f04d5140SColin Leitner } 1079f04d5140SColin Leitner 1080078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 1081078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 1082078328daSJiri Kosina 10836f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 10846f498018SBenjamin Tissoires return 0; 1085f04d5140SColin Leitner } 1086f04d5140SColin Leitner 10875710fabfSAntonio Ospite /* 1088bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1089bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1090bd28ce00SJiri Slaby * events. 1091bd28ce00SJiri Slaby */ 1092816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1093bd28ce00SJiri Slaby { 1094bd28ce00SJiri Slaby int ret; 1095bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 1096bd28ce00SJiri Slaby 1097bd28ce00SJiri Slaby if (!buf) 1098bd28ce00SJiri Slaby return -ENOMEM; 1099bd28ce00SJiri Slaby 1100cafebc05SBenjamin Tissoires ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1101cafebc05SBenjamin Tissoires HID_REQ_GET_REPORT); 1102f204828aSBenjamin Tissoires 1103bd28ce00SJiri Slaby if (ret < 0) 11044291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 1105bd28ce00SJiri Slaby 1106bd28ce00SJiri Slaby kfree(buf); 1107bd28ce00SJiri Slaby 1108bd28ce00SJiri Slaby return ret; 1109bd28ce00SJiri Slaby } 1110bd28ce00SJiri Slaby 1111816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1112f9ce7c28SBastien Nocera { 1113fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 1114b0dd72aaSBenjamin Tissoires return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), 1115b0dd72aaSBenjamin Tissoires HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 1116f9ce7c28SBastien Nocera } 1117f9ce7c28SBastien Nocera 1118ad142b9eSFrank Praznik /* 1119ad142b9eSFrank Praznik * Requesting feature report 0x02 in Bluetooth mode changes the state of the 112068330d83SFrank Praznik * controller so that it sends full input reports of type 0x11. 112168330d83SFrank Praznik */ 112268330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev) 112368330d83SFrank Praznik { 112468330d83SFrank Praznik __u8 buf[37] = { 0 }; 112568330d83SFrank Praznik 112668330d83SFrank Praznik return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), 112768330d83SFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1128bd28ce00SJiri Slaby } 1129bd28ce00SJiri Slaby 11308025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 11318025087aSFrank Praznik { 11328025087aSFrank Praznik static const __u8 sixaxis_leds[10][4] = { 11338025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x00 }, 11348025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x00 }, 11358025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x00 }, 11368025087aSFrank Praznik { 0x00, 0x00, 0x00, 0x01 }, 11378025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x01 }, 11388025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x01 }, 11398025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x01 }, 11408025087aSFrank Praznik { 0x01, 0x00, 0x01, 0x01 }, 11418025087aSFrank Praznik { 0x00, 0x01, 0x01, 0x01 }, 11428025087aSFrank Praznik { 0x01, 0x01, 0x01, 0x01 } 11438025087aSFrank Praznik }; 11448025087aSFrank Praznik 11458025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0])); 11468025087aSFrank Praznik 11478025087aSFrank Praznik if (id < 0) 11488025087aSFrank Praznik return; 11498025087aSFrank Praznik 11508025087aSFrank Praznik id %= 10; 11518025087aSFrank Praznik memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id])); 11528025087aSFrank Praznik } 11538025087aSFrank Praznik 11548025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 11558025087aSFrank Praznik { 11568025087aSFrank Praznik /* The first 4 color/index entries match what the PS4 assigns */ 11578025087aSFrank Praznik static const __u8 color_code[7][3] = { 11588025087aSFrank Praznik /* Blue */ { 0x00, 0x00, 0x01 }, 11598025087aSFrank Praznik /* Red */ { 0x01, 0x00, 0x00 }, 11608025087aSFrank Praznik /* Green */ { 0x00, 0x01, 0x00 }, 11618025087aSFrank Praznik /* Pink */ { 0x02, 0x00, 0x01 }, 11628025087aSFrank Praznik /* Orange */ { 0x02, 0x01, 0x00 }, 11638025087aSFrank Praznik /* Teal */ { 0x00, 0x01, 0x01 }, 11648025087aSFrank Praznik /* White */ { 0x01, 0x01, 0x01 } 11658025087aSFrank Praznik }; 11668025087aSFrank Praznik 11678025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0])); 11688025087aSFrank Praznik 11698025087aSFrank Praznik if (id < 0) 11708025087aSFrank Praznik return; 11718025087aSFrank Praznik 11728025087aSFrank Praznik id %= 7; 11738025087aSFrank Praznik memcpy(values, color_code[id], sizeof(color_code[id])); 11748025087aSFrank Praznik } 11758025087aSFrank Praznik 117660781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 1177f04d5140SColin Leitner { 1178f04d5140SColin Leitner struct list_head *report_list = 1179f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1180f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1181f04d5140SColin Leitner struct hid_report, list); 1182f04d5140SColin Leitner __s32 *value = report->field[0]->value; 1183f04d5140SColin Leitner 1184f04d5140SColin Leitner value[0] = 0x00; 118560781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 118660781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 118760781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 118860781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 1189f04d5140SColin Leitner value[5] = 0x00; 1190f04d5140SColin Leitner value[6] = 0x00; 1191f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1192f04d5140SColin Leitner } 1193f04d5140SColin Leitner 1194fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count) 11950a286ef2SSven Eckelmann { 119660781cf4SFrank Praznik int n; 11970a286ef2SSven Eckelmann 119860781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 119960781cf4SFrank Praznik 1200fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER && count == 4) { 1201fa57a810SFrank Praznik buzz_set_leds(sc->hdev, leds); 1202fee4e2d5SFrank Praznik } else { 120360781cf4SFrank Praznik for (n = 0; n < count; n++) 1204fa57a810SFrank Praznik sc->led_state[n] = leds[n]; 1205fa57a810SFrank Praznik schedule_work(&sc->state_worker); 12060a286ef2SSven Eckelmann } 12070a286ef2SSven Eckelmann } 12080a286ef2SSven Eckelmann 1209c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1210f04d5140SColin Leitner enum led_brightness value) 1211f04d5140SColin Leitner { 1212f04d5140SColin Leitner struct device *dev = led->dev->parent; 1213f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1214f04d5140SColin Leitner struct sony_sc *drv_data; 1215f04d5140SColin Leitner 1216f04d5140SColin Leitner int n; 1217b3ed458cSFrank Praznik int force_update; 1218f04d5140SColin Leitner 1219f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12202251b85fSSven Eckelmann if (!drv_data) { 1221f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1222f04d5140SColin Leitner return; 1223f04d5140SColin Leitner } 1224f04d5140SColin Leitner 1225b3ed458cSFrank Praznik /* 1226b3ed458cSFrank Praznik * The Sixaxis on USB will override any LED settings sent to it 1227b3ed458cSFrank Praznik * and keep flashing all of the LEDs until the PS button is pressed. 1228b3ed458cSFrank Praznik * Updates, even if redundant, must be always be sent to the 1229b3ed458cSFrank Praznik * controller to avoid having to toggle the state of an LED just to 1230b3ed458cSFrank Praznik * stop the flashing later on. 1231b3ed458cSFrank Praznik */ 1232b3ed458cSFrank Praznik force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB); 1233b3ed458cSFrank Praznik 123460781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1235b3ed458cSFrank Praznik if (led == drv_data->leds[n] && (force_update || 1236b3ed458cSFrank Praznik (value != drv_data->led_state[n] || 1237b3ed458cSFrank Praznik drv_data->led_delay_on[n] || 1238b3ed458cSFrank Praznik drv_data->led_delay_off[n]))) { 1239b3ed458cSFrank Praznik 124060781cf4SFrank Praznik drv_data->led_state[n] = value; 1241b3ed458cSFrank Praznik 1242b3ed458cSFrank Praznik /* Setting the brightness stops the blinking */ 1243b3ed458cSFrank Praznik drv_data->led_delay_on[n] = 0; 1244b3ed458cSFrank Praznik drv_data->led_delay_off[n] = 0; 1245b3ed458cSFrank Praznik 1246fa57a810SFrank Praznik sony_set_leds(drv_data, drv_data->led_state, 1247fa57a810SFrank Praznik drv_data->led_count); 1248f04d5140SColin Leitner break; 1249f04d5140SColin Leitner } 1250f04d5140SColin Leitner } 1251f04d5140SColin Leitner } 1252f04d5140SColin Leitner 1253c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1254f04d5140SColin Leitner { 1255f04d5140SColin Leitner struct device *dev = led->dev->parent; 1256f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1257f04d5140SColin Leitner struct sony_sc *drv_data; 1258f04d5140SColin Leitner 1259f04d5140SColin Leitner int n; 1260f04d5140SColin Leitner 1261f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12622251b85fSSven Eckelmann if (!drv_data) { 1263f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1264f04d5140SColin Leitner return LED_OFF; 1265f04d5140SColin Leitner } 1266f04d5140SColin Leitner 126760781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 12687db7504aSSimon Wood if (led == drv_data->leds[n]) 12697db7504aSSimon Wood return drv_data->led_state[n]; 1270f04d5140SColin Leitner } 1271f04d5140SColin Leitner 12727db7504aSSimon Wood return LED_OFF; 1273f04d5140SColin Leitner } 1274f04d5140SColin Leitner 1275b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, 1276b3ed458cSFrank Praznik unsigned long *delay_off) 1277b3ed458cSFrank Praznik { 1278b3ed458cSFrank Praznik struct device *dev = led->dev->parent; 1279b3ed458cSFrank Praznik struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1280b3ed458cSFrank Praznik struct sony_sc *drv_data = hid_get_drvdata(hdev); 1281b3ed458cSFrank Praznik int n; 1282b3ed458cSFrank Praznik __u8 new_on, new_off; 1283b3ed458cSFrank Praznik 1284b3ed458cSFrank Praznik if (!drv_data) { 1285b3ed458cSFrank Praznik hid_err(hdev, "No device data\n"); 1286b3ed458cSFrank Praznik return -EINVAL; 1287b3ed458cSFrank Praznik } 1288b3ed458cSFrank Praznik 1289b3ed458cSFrank Praznik /* Max delay is 255 deciseconds or 2550 milliseconds */ 1290b3ed458cSFrank Praznik if (*delay_on > 2550) 1291b3ed458cSFrank Praznik *delay_on = 2550; 1292b3ed458cSFrank Praznik if (*delay_off > 2550) 1293b3ed458cSFrank Praznik *delay_off = 2550; 1294b3ed458cSFrank Praznik 1295b3ed458cSFrank Praznik /* Blink at 1 Hz if both values are zero */ 1296b3ed458cSFrank Praznik if (!*delay_on && !*delay_off) 1297b3ed458cSFrank Praznik *delay_on = *delay_off = 500; 1298b3ed458cSFrank Praznik 1299b3ed458cSFrank Praznik new_on = *delay_on / 10; 1300b3ed458cSFrank Praznik new_off = *delay_off / 10; 1301b3ed458cSFrank Praznik 1302b3ed458cSFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1303b3ed458cSFrank Praznik if (led == drv_data->leds[n]) 1304b3ed458cSFrank Praznik break; 1305b3ed458cSFrank Praznik } 1306b3ed458cSFrank Praznik 1307b3ed458cSFrank Praznik /* This LED is not registered on this device */ 1308b3ed458cSFrank Praznik if (n >= drv_data->led_count) 1309b3ed458cSFrank Praznik return -EINVAL; 1310b3ed458cSFrank Praznik 1311b3ed458cSFrank Praznik /* Don't schedule work if the values didn't change */ 1312b3ed458cSFrank Praznik if (new_on != drv_data->led_delay_on[n] || 1313b3ed458cSFrank Praznik new_off != drv_data->led_delay_off[n]) { 1314b3ed458cSFrank Praznik drv_data->led_delay_on[n] = new_on; 1315b3ed458cSFrank Praznik drv_data->led_delay_off[n] = new_off; 1316b3ed458cSFrank Praznik schedule_work(&drv_data->state_worker); 1317b3ed458cSFrank Praznik } 1318b3ed458cSFrank Praznik 1319b3ed458cSFrank Praznik return 0; 1320b3ed458cSFrank Praznik } 1321b3ed458cSFrank Praznik 1322fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc) 13230a286ef2SSven Eckelmann { 13240a286ef2SSven Eckelmann struct led_classdev *led; 13250a286ef2SSven Eckelmann int n; 13260a286ef2SSven Eckelmann 1327fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 13280a286ef2SSven Eckelmann 1329fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 1330fa57a810SFrank Praznik led = sc->leds[n]; 1331fa57a810SFrank Praznik sc->leds[n] = NULL; 13320a286ef2SSven Eckelmann if (!led) 13330a286ef2SSven Eckelmann continue; 13340a286ef2SSven Eckelmann led_classdev_unregister(led); 13350a286ef2SSven Eckelmann kfree(led); 13360a286ef2SSven Eckelmann } 133760781cf4SFrank Praznik 1338fa57a810SFrank Praznik sc->led_count = 0; 13390a286ef2SSven Eckelmann } 13400a286ef2SSven Eckelmann 1341fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc) 1342f04d5140SColin Leitner { 1343fa57a810SFrank Praznik struct hid_device *hdev = sc->hdev; 134440e32ee6SJiri Kosina int n, ret = 0; 1345b3ed458cSFrank Praznik int use_ds4_names; 134640e32ee6SJiri Kosina struct led_classdev *led; 134740e32ee6SJiri Kosina size_t name_sz; 134840e32ee6SJiri Kosina char *name; 13490a286ef2SSven Eckelmann size_t name_len; 13500a286ef2SSven Eckelmann const char *name_fmt; 1351b3ed458cSFrank Praznik static const char * const ds4_name_str[] = { "red", "green", "blue", 1352b3ed458cSFrank Praznik "global" }; 13538025087aSFrank Praznik __u8 initial_values[MAX_LEDS] = { 0 }; 1354b3ed458cSFrank Praznik __u8 max_brightness[MAX_LEDS] = { 1 }; 1355b3ed458cSFrank Praznik __u8 use_hw_blink[MAX_LEDS] = { 0 }; 1356f04d5140SColin Leitner 1357fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1358f04d5140SColin Leitner 1359fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER) { 1360fa57a810SFrank Praznik sc->led_count = 4; 1361b3ed458cSFrank Praznik use_ds4_names = 0; 13620a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 13630a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 13649446edb9SKees Cook /* Validate expected report characteristics. */ 13659446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 13669446edb9SKees Cook return -ENODEV; 1367fa57a810SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 13688025087aSFrank Praznik dualshock4_set_leds_from_id(sc->device_id, initial_values); 1369b3ed458cSFrank Praznik initial_values[3] = 1; 1370b3ed458cSFrank Praznik sc->led_count = 4; 1371b3ed458cSFrank Praznik memset(max_brightness, 255, 3); 1372b3ed458cSFrank Praznik use_hw_blink[3] = 1; 1373b3ed458cSFrank Praznik use_ds4_names = 1; 137461ebca93SFrank Praznik name_len = 0; 137561ebca93SFrank Praznik name_fmt = "%s:%s"; 137660781cf4SFrank Praznik } else { 13778025087aSFrank Praznik sixaxis_set_leds_from_id(sc->device_id, initial_values); 1378fa57a810SFrank Praznik sc->led_count = 4; 1379b3ed458cSFrank Praznik memset(use_hw_blink, 1, 4); 1380b3ed458cSFrank Praznik use_ds4_names = 0; 138161ebca93SFrank Praznik name_len = strlen("::sony#"); 138261ebca93SFrank Praznik name_fmt = "%s::sony%d"; 138360781cf4SFrank Praznik } 138460781cf4SFrank Praznik 1385ad142b9eSFrank Praznik /* 1386ad142b9eSFrank Praznik * Clear LEDs as we have no way of reading their initial state. This is 1387f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1388ad142b9eSFrank Praznik * LEDs to on 1389ad142b9eSFrank Praznik */ 1390fa57a810SFrank Praznik sony_set_leds(sc, initial_values, sc->led_count); 1391f04d5140SColin Leitner 13920a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1393f04d5140SColin Leitner 1394fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 139561ebca93SFrank Praznik 1396b3ed458cSFrank Praznik if (use_ds4_names) 1397b3ed458cSFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2; 139861ebca93SFrank Praznik 1399f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1400f04d5140SColin Leitner if (!led) { 1401f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 14028cd5fcdaSJulia Lawall ret = -ENOMEM; 1403f04d5140SColin Leitner goto error_leds; 1404f04d5140SColin Leitner } 1405f04d5140SColin Leitner 1406f04d5140SColin Leitner name = (void *)(&led[1]); 1407b3ed458cSFrank Praznik if (use_ds4_names) 1408b3ed458cSFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), 1409b3ed458cSFrank Praznik ds4_name_str[n]); 141061ebca93SFrank Praznik else 14110a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1412f04d5140SColin Leitner led->name = name; 14138025087aSFrank Praznik led->brightness = initial_values[n]; 1414b3ed458cSFrank Praznik led->max_brightness = max_brightness[n]; 1415c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1416c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1417f04d5140SColin Leitner 1418b3ed458cSFrank Praznik if (use_hw_blink[n]) 1419b3ed458cSFrank Praznik led->blink_set = sony_led_blink_set; 1420b3ed458cSFrank Praznik 14218025087aSFrank Praznik sc->leds[n] = led; 14228025087aSFrank Praznik 14238cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 14248cd5fcdaSJulia Lawall if (ret) { 1425f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 14268025087aSFrank Praznik sc->leds[n] = NULL; 1427f04d5140SColin Leitner kfree(led); 1428f04d5140SColin Leitner goto error_leds; 1429f04d5140SColin Leitner } 1430f04d5140SColin Leitner } 1431f04d5140SColin Leitner 1432f04d5140SColin Leitner return ret; 1433f04d5140SColin Leitner 1434f04d5140SColin Leitner error_leds: 1435fa57a810SFrank Praznik sony_leds_remove(sc); 1436f04d5140SColin Leitner 1437f04d5140SColin Leitner return ret; 1438f04d5140SColin Leitner } 1439f04d5140SColin Leitner 1440cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 1441a08c22c0SSven Eckelmann { 144292b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1443b3ed458cSFrank Praznik int n; 144455d3b664SFrank Praznik union sixaxis_output_report_01 report = { 144555d3b664SFrank Praznik .buf = { 1446a08c22c0SSven Eckelmann 0x01, 1447a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 14480a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1449a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1450a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1451a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1452a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1453a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 145455d3b664SFrank Praznik } 1455a08c22c0SSven Eckelmann }; 14569f323b68SSven Eckelmann 14570a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 145855d3b664SFrank Praznik report.data.rumble.right_motor_on = sc->right ? 1 : 0; 145955d3b664SFrank Praznik report.data.rumble.left_motor_force = sc->left; 14600a286ef2SSven Eckelmann #endif 14610a286ef2SSven Eckelmann 146255d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[0] << 1; 146355d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[1] << 2; 146455d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[2] << 3; 146555d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[3] << 4; 14669f323b68SSven Eckelmann 146788f6576fSSimon Wood /* Set flag for all leds off, required for 3rd party INTEC controller */ 146888f6576fSSimon Wood if ((report.data.leds_bitmap & 0x1E) == 0) 146988f6576fSSimon Wood report.data.leds_bitmap |= 0x20; 147088f6576fSSimon Wood 1471b3ed458cSFrank Praznik /* 1472b3ed458cSFrank Praznik * The LEDs in the report are indexed in reverse order to their 1473b3ed458cSFrank Praznik * corresponding light on the controller. 1474b3ed458cSFrank Praznik * Index 0 = LED 4, index 1 = LED 3, etc... 1475b3ed458cSFrank Praznik * 1476b3ed458cSFrank Praznik * In the case of both delay values being zero (blinking disabled) the 1477b3ed458cSFrank Praznik * default report values should be used or the controller LED will be 1478b3ed458cSFrank Praznik * always off. 1479b3ed458cSFrank Praznik */ 1480b3ed458cSFrank Praznik for (n = 0; n < 4; n++) { 1481b3ed458cSFrank Praznik if (sc->led_delay_on[n] || sc->led_delay_off[n]) { 1482b3ed458cSFrank Praznik report.data.led[3 - n].duty_off = sc->led_delay_off[n]; 1483b3ed458cSFrank Praznik report.data.led[3 - n].duty_on = sc->led_delay_on[n]; 1484b3ed458cSFrank Praznik } 1485b3ed458cSFrank Praznik } 1486b3ed458cSFrank Praznik 148755d3b664SFrank Praznik hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, 148855d3b664SFrank Praznik sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 14899f323b68SSven Eckelmann } 14909f323b68SSven Eckelmann 14910bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 14920bd88dd3SFrank Praznik { 14930bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 14940da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 149548220237SFrank Praznik int offset; 14960da8ea65SFrank Praznik 1497fdcf105dSFrank Praznik __u8 buf[78] = { 0 }; 149848220237SFrank Praznik 1499fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 150048220237SFrank Praznik buf[0] = 0x05; 1501b3ed458cSFrank Praznik buf[1] = 0xFF; 150248220237SFrank Praznik offset = 4; 1503fdcf105dSFrank Praznik } else { 1504fdcf105dSFrank Praznik buf[0] = 0x11; 1505fdcf105dSFrank Praznik buf[1] = 0xB0; 1506fdcf105dSFrank Praznik buf[3] = 0x0F; 1507fdcf105dSFrank Praznik offset = 6; 1508fdcf105dSFrank Praznik } 15090bd88dd3SFrank Praznik 15100bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 151148220237SFrank Praznik buf[offset++] = sc->right; 151248220237SFrank Praznik buf[offset++] = sc->left; 151348220237SFrank Praznik #else 151448220237SFrank Praznik offset += 2; 15150bd88dd3SFrank Praznik #endif 15160bd88dd3SFrank Praznik 1517b3ed458cSFrank Praznik /* LED 3 is the global control */ 1518b3ed458cSFrank Praznik if (sc->led_state[3]) { 151948220237SFrank Praznik buf[offset++] = sc->led_state[0]; 152048220237SFrank Praznik buf[offset++] = sc->led_state[1]; 152148220237SFrank Praznik buf[offset++] = sc->led_state[2]; 1522b3ed458cSFrank Praznik } else { 1523b3ed458cSFrank Praznik offset += 3; 1524b3ed458cSFrank Praznik } 1525b3ed458cSFrank Praznik 1526b3ed458cSFrank Praznik /* If both delay values are zero the DualShock 4 disables blinking. */ 1527b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_on[3]; 1528b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_off[3]; 152960781cf4SFrank Praznik 1530fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1531fdcf105dSFrank Praznik hid_hw_output_report(hdev, buf, 32); 1532fdcf105dSFrank Praznik else 1533fdcf105dSFrank Praznik hid_hw_raw_request(hdev, 0x11, buf, 78, 1534fdcf105dSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 15350bd88dd3SFrank Praznik } 15360bd88dd3SFrank Praznik 15370a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 15389f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 15399f323b68SSven Eckelmann struct ff_effect *effect) 15409f323b68SSven Eckelmann { 1541a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 15429f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 1543a08c22c0SSven Eckelmann 1544a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 1545a08c22c0SSven Eckelmann return 0; 1546a08c22c0SSven Eckelmann 15479f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 15480bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 1549a08c22c0SSven Eckelmann 155092b5c411SSven Eckelmann schedule_work(&sc->state_worker); 15519f323b68SSven Eckelmann return 0; 1552a08c22c0SSven Eckelmann } 1553a08c22c0SSven Eckelmann 1554fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1555a08c22c0SSven Eckelmann { 1556fa57a810SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1557a08c22c0SSven Eckelmann struct hid_input, list); 1558a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 1559a08c22c0SSven Eckelmann 1560a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 1561a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 1562a08c22c0SSven Eckelmann } 1563a08c22c0SSven Eckelmann 1564a08c22c0SSven Eckelmann #else 1565fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1566a08c22c0SSven Eckelmann { 1567a08c22c0SSven Eckelmann return 0; 1568a08c22c0SSven Eckelmann } 15699f323b68SSven Eckelmann 1570a08c22c0SSven Eckelmann #endif 1571a08c22c0SSven Eckelmann 1572d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 1573d902f472SFrank Praznik enum power_supply_property psp, 1574d902f472SFrank Praznik union power_supply_propval *val) 1575c4e1ddf2SFrank Praznik { 1576d902f472SFrank Praznik struct sony_sc *sc = container_of(psy, struct sony_sc, battery); 1577d902f472SFrank Praznik unsigned long flags; 1578d902f472SFrank Praznik int ret = 0; 1579d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 1580c4e1ddf2SFrank Praznik 1581d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 1582d902f472SFrank Praznik battery_charging = sc->battery_charging; 1583d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 1584d902f472SFrank Praznik cable_state = sc->cable_state; 1585d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 1586c4e1ddf2SFrank Praznik 1587d902f472SFrank Praznik switch (psp) { 1588d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 1589d902f472SFrank Praznik val->intval = 1; 1590d902f472SFrank Praznik break; 1591d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 1592d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 1593d902f472SFrank Praznik break; 1594d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 1595d902f472SFrank Praznik val->intval = battery_capacity; 1596d902f472SFrank Praznik break; 1597d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 1598d902f472SFrank Praznik if (battery_charging) 1599d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 1600d902f472SFrank Praznik else 1601d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 1602d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 1603d902f472SFrank Praznik else 1604d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1605d902f472SFrank Praznik break; 1606d902f472SFrank Praznik default: 1607d902f472SFrank Praznik ret = -EINVAL; 1608d902f472SFrank Praznik break; 1609c4e1ddf2SFrank Praznik } 1610d902f472SFrank Praznik return ret; 1611d902f472SFrank Praznik } 1612d902f472SFrank Praznik 1613d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc) 1614d902f472SFrank Praznik { 1615d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 1616d902f472SFrank Praznik int ret; 1617d902f472SFrank Praznik 1618ad142b9eSFrank Praznik /* 1619ad142b9eSFrank Praznik * Set the default battery level to 100% to avoid low battery warnings 1620d9a293a9SFrank Praznik * if the battery is polled before the first device report is received. 1621d9a293a9SFrank Praznik */ 1622d9a293a9SFrank Praznik sc->battery_capacity = 100; 1623d9a293a9SFrank Praznik 1624d902f472SFrank Praznik sc->battery.properties = sony_battery_props; 1625d902f472SFrank Praznik sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); 1626d902f472SFrank Praznik sc->battery.get_property = sony_battery_get_property; 1627d902f472SFrank Praznik sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; 1628d902f472SFrank Praznik sc->battery.use_for_apm = 0; 1629314531f1SFrank Praznik sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR", 1630314531f1SFrank Praznik sc->mac_address); 1631d902f472SFrank Praznik if (!sc->battery.name) 1632d902f472SFrank Praznik return -ENOMEM; 1633d902f472SFrank Praznik 1634d902f472SFrank Praznik ret = power_supply_register(&hdev->dev, &sc->battery); 1635d902f472SFrank Praznik if (ret) { 1636d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 1637d902f472SFrank Praznik goto err_free; 1638d902f472SFrank Praznik } 1639d902f472SFrank Praznik 1640d902f472SFrank Praznik power_supply_powers(&sc->battery, &hdev->dev); 1641d902f472SFrank Praznik return 0; 1642d902f472SFrank Praznik 1643d902f472SFrank Praznik err_free: 1644d902f472SFrank Praznik kfree(sc->battery.name); 1645d902f472SFrank Praznik sc->battery.name = NULL; 1646d902f472SFrank Praznik return ret; 1647d902f472SFrank Praznik } 1648d902f472SFrank Praznik 1649d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 1650d902f472SFrank Praznik { 1651d902f472SFrank Praznik if (!sc->battery.name) 1652d902f472SFrank Praznik return; 1653d902f472SFrank Praznik 1654d902f472SFrank Praznik power_supply_unregister(&sc->battery); 1655d902f472SFrank Praznik kfree(sc->battery.name); 1656d902f472SFrank Praznik sc->battery.name = NULL; 1657d902f472SFrank Praznik } 1658d902f472SFrank Praznik 1659e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1660e5606230SFrank Praznik int w, int h) 1661e5606230SFrank Praznik { 1662e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1663e5606230SFrank Praznik struct hid_input, list); 1664e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 1665e5606230SFrank Praznik int ret; 1666e5606230SFrank Praznik 1667e5606230SFrank Praznik ret = input_mt_init_slots(input_dev, touch_count, 0); 1668e5606230SFrank Praznik if (ret < 0) { 1669e5606230SFrank Praznik hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); 1670e5606230SFrank Praznik return ret; 1671e5606230SFrank Praznik } 1672e5606230SFrank Praznik 1673e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); 1674e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); 1675e5606230SFrank Praznik 1676c4e1ddf2SFrank Praznik return 0; 1677c4e1ddf2SFrank Praznik } 1678e5606230SFrank Praznik 1679d2d782fcSFrank Praznik /* 1680d2d782fcSFrank Praznik * If a controller is plugged in via USB while already connected via Bluetooth 1681d2d782fcSFrank Praznik * it will show up as two devices. A global list of connected controllers and 1682d2d782fcSFrank Praznik * their MAC addresses is maintained to ensure that a device is only connected 1683d2d782fcSFrank Praznik * once. 1684d2d782fcSFrank Praznik */ 1685d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc) 1686d2d782fcSFrank Praznik { 1687d2d782fcSFrank Praznik struct sony_sc *entry; 1688d2d782fcSFrank Praznik unsigned long flags; 1689d2d782fcSFrank Praznik int ret; 1690d2d782fcSFrank Praznik 1691d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1692d2d782fcSFrank Praznik 1693d2d782fcSFrank Praznik list_for_each_entry(entry, &sony_device_list, list_node) { 1694d2d782fcSFrank Praznik ret = memcmp(sc->mac_address, entry->mac_address, 1695d2d782fcSFrank Praznik sizeof(sc->mac_address)); 1696d2d782fcSFrank Praznik if (!ret) { 1697d2d782fcSFrank Praznik ret = -EEXIST; 1698d2d782fcSFrank Praznik hid_info(sc->hdev, "controller with MAC address %pMR already connected\n", 1699d2d782fcSFrank Praznik sc->mac_address); 1700d2d782fcSFrank Praznik goto unlock; 1701d2d782fcSFrank Praznik } 1702c4e1ddf2SFrank Praznik } 1703c4e1ddf2SFrank Praznik 1704d2d782fcSFrank Praznik ret = 0; 1705d2d782fcSFrank Praznik list_add(&(sc->list_node), &sony_device_list); 1706c4e1ddf2SFrank Praznik 1707d2d782fcSFrank Praznik unlock: 1708d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1709d2d782fcSFrank Praznik return ret; 1710d2d782fcSFrank Praznik } 1711d2d782fcSFrank Praznik 1712d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc) 1713d2d782fcSFrank Praznik { 1714d2d782fcSFrank Praznik unsigned long flags; 1715d2d782fcSFrank Praznik 1716d2d782fcSFrank Praznik if (sc->list_node.next) { 1717d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1718d2d782fcSFrank Praznik list_del(&(sc->list_node)); 1719d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1720d2d782fcSFrank Praznik } 1721d2d782fcSFrank Praznik } 1722d2d782fcSFrank Praznik 1723d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc) 1724d2d782fcSFrank Praznik { 1725d2d782fcSFrank Praznik int ret; 1726d2d782fcSFrank Praznik 1727d2d782fcSFrank Praznik /* HIDP stores the device MAC address as a string in the uniq field. */ 1728d2d782fcSFrank Praznik ret = strlen(sc->hdev->uniq); 1729d2d782fcSFrank Praznik if (ret != 17) 1730c4e1ddf2SFrank Praznik return -EINVAL; 1731d2d782fcSFrank Praznik 1732d2d782fcSFrank Praznik ret = sscanf(sc->hdev->uniq, 1733d2d782fcSFrank Praznik "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 1734d2d782fcSFrank Praznik &sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3], 1735d2d782fcSFrank Praznik &sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]); 1736d2d782fcSFrank Praznik 1737d2d782fcSFrank Praznik if (ret != 6) 1738d2d782fcSFrank Praznik return -EINVAL; 1739d2d782fcSFrank Praznik 1740d2d782fcSFrank Praznik return 0; 1741c4e1ddf2SFrank Praznik } 1742c4e1ddf2SFrank Praznik 1743d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc) 1744d2d782fcSFrank Praznik { 1745d2d782fcSFrank Praznik int n, ret; 1746d2d782fcSFrank Praznik 1747d2d782fcSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || 1748d2d782fcSFrank Praznik (sc->quirks & SIXAXIS_CONTROLLER_BT)) { 1749d2d782fcSFrank Praznik /* 1750d2d782fcSFrank Praznik * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC 1751d2d782fcSFrank Praznik * address from the uniq string where HIDP stores it. 1752d2d782fcSFrank Praznik * As uniq cannot be guaranteed to be a MAC address in all cases 1753d2d782fcSFrank Praznik * a failure of this function should not prevent the connection. 1754d2d782fcSFrank Praznik */ 1755d2d782fcSFrank Praznik if (sony_get_bt_devaddr(sc) < 0) { 1756d2d782fcSFrank Praznik hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); 1757d2d782fcSFrank Praznik return 0; 1758d2d782fcSFrank Praznik } 1759d2d782fcSFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1760d2d782fcSFrank Praznik __u8 buf[7]; 1761d2d782fcSFrank Praznik 1762d2d782fcSFrank Praznik /* 1763d2d782fcSFrank Praznik * The MAC address of a DS4 controller connected via USB can be 1764d2d782fcSFrank Praznik * retrieved with feature report 0x81. The address begins at 1765d2d782fcSFrank Praznik * offset 1. 1766d2d782fcSFrank Praznik */ 1767d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf), 1768d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1769d2d782fcSFrank Praznik 1770d2d782fcSFrank Praznik if (ret != 7) { 1771d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); 1772d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1773d2d782fcSFrank Praznik } 1774d2d782fcSFrank Praznik 1775d2d782fcSFrank Praznik memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); 1776d2d782fcSFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1777d2d782fcSFrank Praznik __u8 buf[18]; 1778d2d782fcSFrank Praznik 1779d2d782fcSFrank Praznik /* 1780d2d782fcSFrank Praznik * The MAC address of a Sixaxis controller connected via USB can 1781d2d782fcSFrank Praznik * be retrieved with feature report 0xf2. The address begins at 1782d2d782fcSFrank Praznik * offset 4. 1783d2d782fcSFrank Praznik */ 1784d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf), 1785d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1786d2d782fcSFrank Praznik 1787d2d782fcSFrank Praznik if (ret != 18) { 1788d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); 1789d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1790d2d782fcSFrank Praznik } 1791d2d782fcSFrank Praznik 1792d2d782fcSFrank Praznik /* 1793d2d782fcSFrank Praznik * The Sixaxis device MAC in the report is big-endian and must 1794d2d782fcSFrank Praznik * be byte-swapped. 1795d2d782fcSFrank Praznik */ 1796d2d782fcSFrank Praznik for (n = 0; n < 6; n++) 1797d2d782fcSFrank Praznik sc->mac_address[5-n] = buf[4+n]; 1798d2d782fcSFrank Praznik } else { 1799d2d782fcSFrank Praznik return 0; 1800d2d782fcSFrank Praznik } 1801d2d782fcSFrank Praznik 1802d2d782fcSFrank Praznik return sony_check_add_dev_list(sc); 1803d2d782fcSFrank Praznik } 1804d2d782fcSFrank Praznik 18058025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc) 18068025087aSFrank Praznik { 18078025087aSFrank Praznik int ret; 18088025087aSFrank Praznik 18098025087aSFrank Praznik /* 18108025087aSFrank Praznik * Only DualShock 4 or Sixaxis controllers get an id. 18118025087aSFrank Praznik * All others are set to -1. 18128025087aSFrank Praznik */ 18138025087aSFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) || 18148025087aSFrank Praznik (sc->quirks & DUALSHOCK4_CONTROLLER)) { 18158025087aSFrank Praznik ret = ida_simple_get(&sony_device_id_allocator, 0, 0, 18168025087aSFrank Praznik GFP_KERNEL); 18178025087aSFrank Praznik if (ret < 0) { 18188025087aSFrank Praznik sc->device_id = -1; 18198025087aSFrank Praznik return ret; 18208025087aSFrank Praznik } 18218025087aSFrank Praznik sc->device_id = ret; 18228025087aSFrank Praznik } else { 18238025087aSFrank Praznik sc->device_id = -1; 18248025087aSFrank Praznik } 18258025087aSFrank Praznik 18268025087aSFrank Praznik return 0; 18278025087aSFrank Praznik } 18288025087aSFrank Praznik 18298025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc) 18308025087aSFrank Praznik { 18318025087aSFrank Praznik if (sc->device_id >= 0) { 18328025087aSFrank Praznik ida_simple_remove(&sony_device_id_allocator, sc->device_id); 18338025087aSFrank Praznik sc->device_id = -1; 18348025087aSFrank Praznik } 18358025087aSFrank Praznik } 18368025087aSFrank Praznik 183746262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc, 183846262047SFrank Praznik void (*worker)(struct work_struct *)) 183946262047SFrank Praznik { 184046262047SFrank Praznik if (!sc->worker_initialized) 184146262047SFrank Praznik INIT_WORK(&sc->state_worker, worker); 184246262047SFrank Praznik 184346262047SFrank Praznik sc->worker_initialized = 1; 184446262047SFrank Praznik } 184546262047SFrank Praznik 184646262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc) 184746262047SFrank Praznik { 184846262047SFrank Praznik if (sc->worker_initialized) 184946262047SFrank Praznik cancel_work_sync(&sc->state_worker); 185046262047SFrank Praznik } 1851d2d782fcSFrank Praznik 1852bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1853bd28ce00SJiri Slaby { 1854bd28ce00SJiri Slaby int ret; 1855cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1856cc6e0bbbSJiri Kosina struct sony_sc *sc; 1857f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1858cc6e0bbbSJiri Kosina 1859abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1860cc6e0bbbSJiri Kosina if (sc == NULL) { 18614291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1862cc6e0bbbSJiri Kosina return -ENOMEM; 1863cc6e0bbbSJiri Kosina } 1864cc6e0bbbSJiri Kosina 1865cc6e0bbbSJiri Kosina sc->quirks = quirks; 1866cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 18670a286ef2SSven Eckelmann sc->hdev = hdev; 1868bd28ce00SJiri Slaby 1869bd28ce00SJiri Slaby ret = hid_parse(hdev); 1870bd28ce00SJiri Slaby if (ret) { 18714291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1872abf832bfSBenjamin Tissoires return ret; 1873bd28ce00SJiri Slaby } 1874bd28ce00SJiri Slaby 1875f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1876f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 187750764650SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER) 1878f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1879f04d5140SColin Leitner 1880f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1881bd28ce00SJiri Slaby if (ret) { 18824291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1883abf832bfSBenjamin Tissoires return ret; 1884bd28ce00SJiri Slaby } 1885bd28ce00SJiri Slaby 18868025087aSFrank Praznik ret = sony_set_device_id(sc); 18878025087aSFrank Praznik if (ret < 0) { 18888025087aSFrank Praznik hid_err(hdev, "failed to allocate the device id\n"); 18898025087aSFrank Praznik goto err_stop; 18908025087aSFrank Praznik } 18918025087aSFrank Praznik 1892569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1893e534a935SBenjamin Tissoires /* 1894e534a935SBenjamin Tissoires * The Sony Sixaxis does not handle HID Output Reports on the 1895e534a935SBenjamin Tissoires * Interrupt EP like it could, so we need to force HID Output 1896e534a935SBenjamin Tissoires * Reports to use HID_REQ_SET_REPORT on the Control EP. 1897e534a935SBenjamin Tissoires * 1898e534a935SBenjamin Tissoires * There is also another issue about HID Output Reports via USB, 1899e534a935SBenjamin Tissoires * the Sixaxis does not want the report_id as part of the data 1900e534a935SBenjamin Tissoires * packet, so we have to discard buf[0] when sending the actual 1901e534a935SBenjamin Tissoires * control message, even for numbered reports, humpf! 1902e534a935SBenjamin Tissoires */ 1903e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1904e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; 1905816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 190646262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1907fee4e2d5SFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) { 19082078b9bbSFrank Praznik /* 19092078b9bbSFrank Praznik * The Sixaxis wants output reports sent on the ctrl endpoint 19102078b9bbSFrank Praznik * when connected via Bluetooth. 19112078b9bbSFrank Praznik */ 19122078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1913816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 191446262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1915fee4e2d5SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 191668330d83SFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { 19172078b9bbSFrank Praznik /* 19182078b9bbSFrank Praznik * The DualShock 4 wants output reports sent on the ctrl 19192078b9bbSFrank Praznik * endpoint when connected via Bluetooth. 19202078b9bbSFrank Praznik */ 19212078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 192268330d83SFrank Praznik ret = dualshock4_set_operational_bt(hdev); 192368330d83SFrank Praznik if (ret < 0) { 192468330d83SFrank Praznik hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); 192568330d83SFrank Praznik goto err_stop; 192668330d83SFrank Praznik } 192768330d83SFrank Praznik } 1928ad142b9eSFrank Praznik /* 1929ad142b9eSFrank Praznik * The Dualshock 4 touchpad supports 2 touches and has a 1930e5606230SFrank Praznik * resolution of 1920x940. 1931e5606230SFrank Praznik */ 1932e5606230SFrank Praznik ret = sony_register_touchpad(sc, 2, 1920, 940); 1933c4e1ddf2SFrank Praznik if (ret < 0) 1934c4e1ddf2SFrank Praznik goto err_stop; 1935c4e1ddf2SFrank Praznik 193646262047SFrank Praznik sony_init_work(sc, dualshock4_state_worker); 19370bd88dd3SFrank Praznik } else { 19380bd88dd3SFrank Praznik ret = 0; 19390bd88dd3SFrank Praznik } 1940f9ce7c28SBastien Nocera 19414dfdc464SJiri Kosina if (ret < 0) 1942bd28ce00SJiri Slaby goto err_stop; 1943bd28ce00SJiri Slaby 1944d2d782fcSFrank Praznik ret = sony_check_add(sc); 1945d2d782fcSFrank Praznik if (ret < 0) 1946d2d782fcSFrank Praznik goto err_stop; 1947d2d782fcSFrank Praznik 19480a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 1949fa57a810SFrank Praznik ret = sony_leds_init(sc); 19500a286ef2SSven Eckelmann if (ret < 0) 19510a286ef2SSven Eckelmann goto err_stop; 19520a286ef2SSven Eckelmann } 19530a286ef2SSven Eckelmann 1954d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1955d902f472SFrank Praznik ret = sony_battery_probe(sc); 1956a08c22c0SSven Eckelmann if (ret < 0) 1957a08c22c0SSven Eckelmann goto err_stop; 1958a08c22c0SSven Eckelmann 1959d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 1960d902f472SFrank Praznik ret = hid_hw_open(hdev); 1961d902f472SFrank Praznik if (ret < 0) { 1962d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 1963d902f472SFrank Praznik goto err_stop; 1964d902f472SFrank Praznik } 1965d902f472SFrank Praznik } 1966d902f472SFrank Praznik 1967c8de9dbbSFrank Praznik if (sc->quirks & SONY_FF_SUPPORT) { 1968fa57a810SFrank Praznik ret = sony_init_ff(sc); 1969d902f472SFrank Praznik if (ret < 0) 1970d902f472SFrank Praznik goto err_close; 19715f5750d2SFrank Praznik } 1972bd28ce00SJiri Slaby 1973f425458eSH Hartley Sweeten return 0; 1974d902f472SFrank Praznik err_close: 1975d902f472SFrank Praznik hid_hw_close(hdev); 1976bd28ce00SJiri Slaby err_stop: 19770a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1978fa57a810SFrank Praznik sony_leds_remove(sc); 1979d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 1980d902f472SFrank Praznik sony_battery_remove(sc); 198146262047SFrank Praznik sony_cancel_work_sync(sc); 1982d2d782fcSFrank Praznik sony_remove_dev_list(sc); 19838025087aSFrank Praznik sony_release_device_id(sc); 1984bd28ce00SJiri Slaby hid_hw_stop(hdev); 1985bd28ce00SJiri Slaby return ret; 1986bd28ce00SJiri Slaby } 1987bd28ce00SJiri Slaby 1988bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev) 1989bd28ce00SJiri Slaby { 1990bd28ce00SJiri Slaby struct sony_sc *sc = hid_get_drvdata(hdev); 1991bd28ce00SJiri Slaby 19920a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1993fa57a810SFrank Praznik sony_leds_remove(sc); 1994bd28ce00SJiri Slaby 1995d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1996d902f472SFrank Praznik hid_hw_close(hdev); 1997d902f472SFrank Praznik sony_battery_remove(sc); 1998d902f472SFrank Praznik } 1999d902f472SFrank Praznik 200046262047SFrank Praznik sony_cancel_work_sync(sc); 20019f323b68SSven Eckelmann 2002d2d782fcSFrank Praznik sony_remove_dev_list(sc); 2003bd28ce00SJiri Slaby 20048025087aSFrank Praznik sony_release_device_id(sc); 20058025087aSFrank Praznik 2006bd28ce00SJiri Slaby hid_hw_stop(hdev); 2007bd28ce00SJiri Slaby } 2008bd28ce00SJiri Slaby 2009bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 2010bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2011bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 2012bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 2013bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 2014bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2015bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_BT }, 2016bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 2017bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2018bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 2019bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2020bd28ce00SJiri Slaby /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 2021bd28ce00SJiri Slaby * Logitech joystick from the device descriptor. */ 2022bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 2023bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2024bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 2025bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2026bd28ce00SJiri Slaby /* PS3 BD Remote Control */ 2027bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 2028bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 2029bd28ce00SJiri Slaby /* Logitech Harmony Adapter for PS3 */ 2030bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 2031bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 20320bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 20330bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 20348ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 20350bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 20368ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 2037bd28ce00SJiri Slaby { } 2038bd28ce00SJiri Slaby }; 2039bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 2040bd28ce00SJiri Slaby 2041bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 2042bd28ce00SJiri Slaby .name = "sony", 2043bd28ce00SJiri Slaby .id_table = sony_devices, 2044bd28ce00SJiri Slaby .input_mapping = sony_mapping, 2045bd28ce00SJiri Slaby .probe = sony_probe, 2046bd28ce00SJiri Slaby .remove = sony_remove, 2047bd28ce00SJiri Slaby .report_fixup = sony_report_fixup, 2048bd28ce00SJiri Slaby .raw_event = sony_raw_event 2049bd28ce00SJiri Slaby }; 20508025087aSFrank Praznik 20518025087aSFrank Praznik static int __init sony_init(void) 20528025087aSFrank Praznik { 20538025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20548025087aSFrank Praznik 20558025087aSFrank Praznik return hid_register_driver(&sony_driver); 20568025087aSFrank Praznik } 20578025087aSFrank Praznik 20588025087aSFrank Praznik static void __exit sony_exit(void) 20598025087aSFrank Praznik { 20608025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20618025087aSFrank Praznik 20628025087aSFrank Praznik ida_destroy(&sony_device_id_allocator); 20638025087aSFrank Praznik hid_unregister_driver(&sony_driver); 20648025087aSFrank Praznik } 20658025087aSFrank Praznik module_init(sony_init); 20668025087aSFrank Praznik module_exit(sony_exit); 2067bd28ce00SJiri Slaby 2068bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 2069