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 20*ad142b9eSFrank Praznik /* 21*ad142b9eSFrank 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> 32bd28ce00SJiri Slaby #include <linux/usb.h> 3340e32ee6SJiri Kosina #include <linux/leds.h> 34d902f472SFrank Praznik #include <linux/power_supply.h> 35d902f472SFrank Praznik #include <linux/spinlock.h> 36e5606230SFrank Praznik #include <linux/input/mt.h> 37bd28ce00SJiri Slaby 38bd28ce00SJiri Slaby #include "hid-ids.h" 39bd28ce00SJiri Slaby 40f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 41f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 43f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 44f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 458ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 47cc6e0bbbSJiri Kosina 48fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 4968330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ 5068330d83SFrank Praznik DUALSHOCK4_CONTROLLER_BT) 51fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 5268330d83SFrank Praznik DUALSHOCK4_CONTROLLER) 53fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 5460781cf4SFrank Praznik 5560781cf4SFrank Praznik #define MAX_LEDS 4 560a286ef2SSven Eckelmann 5761ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 5861ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 5961ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 6061ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 6161ab44beSSimon Wood }; 6261ab44beSSimon Wood 63e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = { 64e57a67daSMauro Carvalho Chehab 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 65e57a67daSMauro Carvalho Chehab 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 66e57a67daSMauro Carvalho Chehab 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 67e57a67daSMauro Carvalho Chehab 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 68e57a67daSMauro Carvalho Chehab 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 69e57a67daSMauro Carvalho Chehab 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 70e57a67daSMauro Carvalho Chehab 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 71e57a67daSMauro Carvalho Chehab 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 72e57a67daSMauro Carvalho Chehab 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 73e57a67daSMauro Carvalho Chehab 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 74e57a67daSMauro Carvalho Chehab 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 75e57a67daSMauro Carvalho Chehab 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 76e57a67daSMauro Carvalho Chehab 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 77e57a67daSMauro Carvalho Chehab 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 78e57a67daSMauro Carvalho Chehab 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 79e57a67daSMauro Carvalho Chehab 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 80e57a67daSMauro Carvalho Chehab 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 81e57a67daSMauro Carvalho Chehab 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 82e57a67daSMauro Carvalho Chehab 0xb1, 0x02, 0xc0, 0xc0, 83e57a67daSMauro Carvalho Chehab }; 84e57a67daSMauro Carvalho Chehab 85*ad142b9eSFrank Praznik /* 86*ad142b9eSFrank Praznik * The default descriptor doesn't provide mapping for the accelerometers 8758d7027bSFrank Praznik * or orientation sensors. This fixed descriptor maps the accelerometers 8858d7027bSFrank Praznik * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors 8958d7027bSFrank Praznik * to usage values 0x43, 0x44 and 0x45. 9058d7027bSFrank Praznik */ 91ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = { 9258d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 9358d7027bSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 9458d7027bSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 9558d7027bSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 9658d7027bSFrank Praznik 0x09, 0x30, /* Usage (X), */ 9758d7027bSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 9858d7027bSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 9958d7027bSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 10058d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 10158d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 10258d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 10358d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 10458d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 10558d7027bSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 10658d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 10758d7027bSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 10858d7027bSFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 10958d7027bSFrank Praznik 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 11058d7027bSFrank Praznik 0x65, 0x14, /* Unit (Degrees), */ 11158d7027bSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 11258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 11358d7027bSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 11458d7027bSFrank Praznik 0x65, 0x00, /* Unit, */ 11558d7027bSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 11658d7027bSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 11758d7027bSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 11858d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 11958d7027bSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 12058d7027bSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 12158d7027bSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 12258d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 12358d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 12458d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 12558d7027bSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 12658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 12758d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 12858d7027bSFrank Praznik 0x25, 0x7F, /* Logical Maximum (127), */ 12958d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 13058d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 13158d7027bSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 13258d7027bSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 13358d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 13458d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 13558d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 13658d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 13758d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 13858d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 13958d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 14058d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 14158d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 14258d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 14358d7027bSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 14458d7027bSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 14558d7027bSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 14658d7027bSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 14758d7027bSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 14858d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 14958d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15058d7027bSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 15158d7027bSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 15258d7027bSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 15358d7027bSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 15458d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 15558d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15658d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 15758d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 15858d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 15958d7027bSFrank Praznik 0x25, 0xFF, /* Logical Maximum (255), */ 16058d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 16158d7027bSFrank Praznik 0x95, 0x27, /* Report Count (39), */ 16258d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 16358d7027bSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 16458d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 16558d7027bSFrank Praznik 0x95, 0x1F, /* Report Count (31), */ 16658d7027bSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 16758d7027bSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 16858d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 16958d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 17058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17158d7027bSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 17258d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 17358d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 17458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17558d7027bSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 17658d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 17758d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 17858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17958d7027bSFrank Praznik 0x85, 0x10, /* Report ID (16), */ 18058d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 18158d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 18258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18358d7027bSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 18458d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 18558d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 18658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18758d7027bSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 18858d7027bSFrank Praznik 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ 18958d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 19058d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 19158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19258d7027bSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 19358d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 19458d7027bSFrank Praznik 0x95, 0x16, /* Report Count (22), */ 19558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19658d7027bSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 19758d7027bSFrank Praznik 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ 19858d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 19958d7027bSFrank Praznik 0x95, 0x10, /* Report Count (16), */ 20058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20158d7027bSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 20258d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 20358d7027bSFrank Praznik 0x95, 0x2C, /* Report Count (44), */ 20458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20558d7027bSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 20658d7027bSFrank Praznik 0x85, 0x80, /* Report ID (128), */ 20758d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 20858d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 20958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21058d7027bSFrank Praznik 0x85, 0x81, /* Report ID (129), */ 21158d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 21258d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 21358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21458d7027bSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 21558d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 21658d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 21758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21858d7027bSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 21958d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 22058d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 22158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22258d7027bSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 22358d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 22458d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 22558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22658d7027bSFrank Praznik 0x85, 0x85, /* Report ID (133), */ 22758d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 22858d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 22958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23058d7027bSFrank Praznik 0x85, 0x86, /* Report ID (134), */ 23158d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 23258d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 23358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23458d7027bSFrank Praznik 0x85, 0x87, /* Report ID (135), */ 23558d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 23658d7027bSFrank Praznik 0x95, 0x23, /* Report Count (35), */ 23758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23858d7027bSFrank Praznik 0x85, 0x88, /* Report ID (136), */ 23958d7027bSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 24058d7027bSFrank Praznik 0x95, 0x22, /* Report Count (34), */ 24158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24258d7027bSFrank Praznik 0x85, 0x89, /* Report ID (137), */ 24358d7027bSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 24458d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 24558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24658d7027bSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 24758d7027bSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 24858d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 24958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25058d7027bSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 25158d7027bSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 25258d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 25358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25458d7027bSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 25558d7027bSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 25658d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 25758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25858d7027bSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 25958d7027bSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 26058d7027bSFrank Praznik 0x95, 0x0C, /* Report Count (12), */ 26158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26258d7027bSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 26358d7027bSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 26458d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 26558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26658d7027bSFrank Praznik 0x85, 0xA1, /* Report ID (161), */ 26758d7027bSFrank Praznik 0x09, 0x41, /* Usage (41h), */ 26858d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 26958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27058d7027bSFrank Praznik 0x85, 0xA2, /* Report ID (162), */ 27158d7027bSFrank Praznik 0x09, 0x42, /* Usage (42h), */ 27258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 27358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27458d7027bSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 27558d7027bSFrank Praznik 0x09, 0x43, /* Usage (43h), */ 27658d7027bSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 27758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27858d7027bSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 27958d7027bSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 28058d7027bSFrank Praznik 0x95, 0x0D, /* Report Count (13), */ 28158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28258d7027bSFrank Praznik 0x85, 0xA5, /* Report ID (165), */ 28358d7027bSFrank Praznik 0x09, 0x45, /* Usage (45h), */ 28458d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 28558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28658d7027bSFrank Praznik 0x85, 0xA6, /* Report ID (166), */ 28758d7027bSFrank Praznik 0x09, 0x46, /* Usage (46h), */ 28858d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 28958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29058d7027bSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 29158d7027bSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 29258d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 29358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29458d7027bSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 29558d7027bSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 29658d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 29758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29858d7027bSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 29958d7027bSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 30058d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 30158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30258d7027bSFrank Praznik 0x85, 0xA7, /* Report ID (167), */ 30358d7027bSFrank Praznik 0x09, 0x4A, /* Usage (4Ah), */ 30458d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 30558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30658d7027bSFrank Praznik 0x85, 0xA8, /* Report ID (168), */ 30758d7027bSFrank Praznik 0x09, 0x4B, /* Usage (4Bh), */ 30858d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 30958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31058d7027bSFrank Praznik 0x85, 0xA9, /* Report ID (169), */ 31158d7027bSFrank Praznik 0x09, 0x4C, /* Usage (4Ch), */ 31258d7027bSFrank Praznik 0x95, 0x08, /* Report Count (8), */ 31358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31458d7027bSFrank Praznik 0x85, 0xAA, /* Report ID (170), */ 31558d7027bSFrank Praznik 0x09, 0x4E, /* Usage (4Eh), */ 31658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 31758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31858d7027bSFrank Praznik 0x85, 0xAB, /* Report ID (171), */ 31958d7027bSFrank Praznik 0x09, 0x4F, /* Usage (4Fh), */ 32058d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 32158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32258d7027bSFrank Praznik 0x85, 0xAC, /* Report ID (172), */ 32358d7027bSFrank Praznik 0x09, 0x50, /* Usage (50h), */ 32458d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 32558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32658d7027bSFrank Praznik 0x85, 0xAD, /* Report ID (173), */ 32758d7027bSFrank Praznik 0x09, 0x51, /* Usage (51h), */ 32858d7027bSFrank Praznik 0x95, 0x0B, /* Report Count (11), */ 32958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33058d7027bSFrank Praznik 0x85, 0xAE, /* Report ID (174), */ 33158d7027bSFrank Praznik 0x09, 0x52, /* Usage (52h), */ 33258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 33358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33458d7027bSFrank Praznik 0x85, 0xAF, /* Report ID (175), */ 33558d7027bSFrank Praznik 0x09, 0x53, /* Usage (53h), */ 33658d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 33758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33858d7027bSFrank Praznik 0x85, 0xB0, /* Report ID (176), */ 33958d7027bSFrank Praznik 0x09, 0x54, /* Usage (54h), */ 34058d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 34158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34258d7027bSFrank Praznik 0xC0 /* End Collection */ 343ed19d8cfSFrank Praznik }; 344ed19d8cfSFrank Praznik 345*ad142b9eSFrank Praznik /* 346*ad142b9eSFrank Praznik * The default behavior of the Dualshock 4 is to send reports using report 347d829674dSFrank Praznik * type 1 when running over Bluetooth. However, as soon as it receives a 348d829674dSFrank Praznik * report of type 17 to set the LEDs or rumble it starts returning it's state 349d829674dSFrank Praznik * in report 17 instead of 1. Since report 17 is undefined in the default HID 350d829674dSFrank Praznik * descriptor the button and axis definitions must be moved to report 17 or 351d829674dSFrank Praznik * the HID layer won't process the received input once a report is sent. 352d829674dSFrank Praznik */ 353d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = { 354d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 355d829674dSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 356d829674dSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 357d829674dSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 358d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 359d829674dSFrank Praznik 0x95, 0x0A, /* Report Count (9), */ 360d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 361d829674dSFrank Praznik 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ 362d829674dSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 363d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 364d829674dSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 365d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 366d829674dSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 367d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 368d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 369d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 370d829674dSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 371d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 372d829674dSFrank Praznik 0x95, 0x28, /* Report Count (40), */ 373d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 374d829674dSFrank Praznik 0x85, 0x06, /* Report ID (6), */ 375d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 376d829674dSFrank Praznik 0x95, 0x34, /* Report Count (52), */ 377d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 378d829674dSFrank Praznik 0x85, 0x07, /* Report ID (7), */ 379d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 380d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 381d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 382d829674dSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 383d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 384d829674dSFrank Praznik 0x95, 0x2F, /* Report Count (47), */ 385d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 386d829674dSFrank Praznik 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ 387d829674dSFrank Praznik 0x85, 0x03, /* Report ID (3), */ 388d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 389d829674dSFrank Praznik 0x95, 0x26, /* Report Count (38), */ 390d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 391d829674dSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 392d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 393d829674dSFrank Praznik 0x95, 0x2E, /* Report Count (46), */ 394d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 395d829674dSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 396d829674dSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 397d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 398d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 399d829674dSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 400d829674dSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 401d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 402d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 403d829674dSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 404d829674dSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 405d829674dSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 406d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 407d829674dSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 408d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 409d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 410d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 411d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 412d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 413d829674dSFrank Praznik 0x09, 0x30, /* Usage (X), */ 414d829674dSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 415d829674dSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 416d829674dSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 417d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 418d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 419d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 420d829674dSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 421d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 422d829674dSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 423d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 424d829674dSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 425d829674dSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 426d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 427d829674dSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 428d829674dSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 429d829674dSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 430d829674dSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 431d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 432d829674dSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 433d829674dSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 434d829674dSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 435d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 436d829674dSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 437d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 438d829674dSFrank Praznik 0x81, 0x01, /* Input (Constant), */ 439d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 440d829674dSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 441d829674dSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 442d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 443d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 444d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 445d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 446d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 447d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 448d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 449d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 450d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 451d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 452d829674dSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 453d829674dSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 454d829674dSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 455d829674dSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 456d829674dSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 457d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 458d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 459d829674dSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 460d829674dSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 461d829674dSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 462d829674dSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 463d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 464d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 465d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 466d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 467d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 468d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 469d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 470d829674dSFrank Praznik 0x95, 0x31, /* Report Count (51), */ 471d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 472d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 473d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 474d829674dSFrank Praznik 0x95, 0x4D, /* Report Count (77), */ 475d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 476d829674dSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 477d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 478d829674dSFrank Praznik 0x95, 0x8D, /* Report Count (141), */ 479d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 480d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 481d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 482d829674dSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 483d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 484d829674dSFrank Praznik 0x95, 0xCD, /* Report Count (205), */ 485d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 486d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 487d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 488d829674dSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 489d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 490d829674dSFrank Praznik 0x96, 0x0D, 0x01, /* Report Count (269), */ 491d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 492d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 493d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 494d829674dSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 495d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 496d829674dSFrank Praznik 0x96, 0x4D, 0x01, /* Report Count (333), */ 497d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 498d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 499d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 500d829674dSFrank Praznik 0x85, 0x16, /* Report ID (22), */ 501d829674dSFrank Praznik 0x09, 0x2A, /* Usage (2Ah), */ 502d829674dSFrank Praznik 0x96, 0x8D, 0x01, /* Report Count (397), */ 503d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 504d829674dSFrank Praznik 0x09, 0x2B, /* Usage (2Bh), */ 505d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 506d829674dSFrank Praznik 0x85, 0x17, /* Report ID (23), */ 507d829674dSFrank Praznik 0x09, 0x2C, /* Usage (2Ch), */ 508d829674dSFrank Praznik 0x96, 0xCD, 0x01, /* Report Count (461), */ 509d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 510d829674dSFrank Praznik 0x09, 0x2D, /* Usage (2Dh), */ 511d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 512d829674dSFrank Praznik 0x85, 0x18, /* Report ID (24), */ 513d829674dSFrank Praznik 0x09, 0x2E, /* Usage (2Eh), */ 514d829674dSFrank Praznik 0x96, 0x0D, 0x02, /* Report Count (525), */ 515d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 516d829674dSFrank Praznik 0x09, 0x2F, /* Usage (2Fh), */ 517d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 518d829674dSFrank Praznik 0x85, 0x19, /* Report ID (25), */ 519d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 520d829674dSFrank Praznik 0x96, 0x22, 0x02, /* Report Count (546), */ 521d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 522d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 523d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 524d829674dSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 525d829674dSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 526d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 527d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 528d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 529d829674dSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 530d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 531d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 532d829674dSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 533d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 534d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 535d829674dSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 536d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 537d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 538d829674dSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 539d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 540d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 541d829674dSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 542d829674dSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 543d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 544d829674dSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 545d829674dSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 546d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 547d829674dSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 548d829674dSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 549d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 550d829674dSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 551d829674dSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 552d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 553d829674dSFrank Praznik 0xC0 /* End Collection */ 554d829674dSFrank Praznik }; 555d829674dSFrank Praznik 556078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 557078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 558078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 559078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 560078328daSJiri Kosina 561078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 562078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 563078328daSJiri Kosina 564078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 565078328daSJiri Kosina * number but it's not needed for correct operation */ 566078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 567078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 568078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 569078328daSJiri Kosina 570078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 571078328daSJiri Kosina * buttons multiple keypresses are allowed */ 572078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 573078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 574078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 575078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 576078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 577078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 578078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 579078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 580078328daSJiri Kosina 581078328daSJiri Kosina 0xC0, /* MEndCollection */ 582078328daSJiri Kosina 583078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 584078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 585078328daSJiri Kosina 586078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 587078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 588078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 589078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 590078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 591078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 592078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 593078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 594078328daSJiri Kosina 0x80, /* MInput */ 595078328daSJiri Kosina 596078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 597078328daSJiri Kosina * 0xff and 11th is for press indication */ 598078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 599078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 600078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 601078328daSJiri Kosina 602078328daSJiri Kosina /* 12th byte is for battery strength */ 603078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 604078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 605078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 606078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 607078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 608078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 609078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 610078328daSJiri Kosina 611078328daSJiri Kosina 0xC0, /* MEndCollection */ 612078328daSJiri Kosina 613078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 614078328daSJiri Kosina }; 615078328daSJiri Kosina 616078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 617078328daSJiri Kosina [0x01] = KEY_SELECT, 618078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 619078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 620078328daSJiri Kosina [0x04] = BTN_START, 621078328daSJiri Kosina [0x05] = KEY_UP, 622078328daSJiri Kosina [0x06] = KEY_RIGHT, 623078328daSJiri Kosina [0x07] = KEY_DOWN, 624078328daSJiri Kosina [0x08] = KEY_LEFT, 625078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 626078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 627078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 628078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 629078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 630078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 631078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 632078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 633078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 634078328daSJiri Kosina [0x14] = KEY_ENTER, 635078328daSJiri Kosina }; 636078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 637078328daSJiri Kosina [0x00] = KEY_1, 638078328daSJiri Kosina [0x01] = KEY_2, 639078328daSJiri Kosina [0x02] = KEY_3, 640078328daSJiri Kosina [0x03] = KEY_4, 641078328daSJiri Kosina [0x04] = KEY_5, 642078328daSJiri Kosina [0x05] = KEY_6, 643078328daSJiri Kosina [0x06] = KEY_7, 644078328daSJiri Kosina [0x07] = KEY_8, 645078328daSJiri Kosina [0x08] = KEY_9, 646078328daSJiri Kosina [0x09] = KEY_0, 647078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 648078328daSJiri Kosina [0x0f] = KEY_CLEAR, 649078328daSJiri Kosina [0x16] = KEY_EJECTCD, 650078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 651078328daSJiri Kosina [0x28] = KEY_TIME, 652078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 653078328daSJiri Kosina [0x31] = KEY_NEXT, 654078328daSJiri Kosina [0x32] = KEY_PLAY, 655078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 656078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 657078328daSJiri Kosina [0x38] = KEY_STOP, 658078328daSJiri Kosina [0x39] = KEY_PAUSE, 659078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 660078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 661078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 662078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 663078328daSJiri Kosina [0x64] = KEY_AUDIO, 664078328daSJiri Kosina [0x65] = KEY_ANGLE, 665078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 666078328daSJiri Kosina [0x80] = KEY_BLUE, 667078328daSJiri Kosina [0x81] = KEY_RED, 668078328daSJiri Kosina [0x82] = KEY_GREEN, 669078328daSJiri Kosina [0x83] = KEY_YELLOW, 670078328daSJiri Kosina }; 671078328daSJiri Kosina 672f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 673*ad142b9eSFrank Praznik /* 674*ad142b9eSFrank Praznik * The controller has 4 remote buzzers, each with one LED and 5 675f04d5140SColin Leitner * buttons. 676f04d5140SColin Leitner * 677f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 678f04d5140SColin Leitner * 679f04d5140SColin Leitner * Key Offset 680f04d5140SColin Leitner * ------------------- 681f04d5140SColin Leitner * Buzz 1 682f04d5140SColin Leitner * Blue 5 683f04d5140SColin Leitner * Orange 4 684f04d5140SColin Leitner * Green 3 685f04d5140SColin Leitner * Yellow 2 686f04d5140SColin Leitner * 687f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 688f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 689f04d5140SColin Leitner */ 690f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 691f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 692f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 693f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 694f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 695f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 696f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 697f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 698f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 699f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 700f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 701f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 702f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 703f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 704f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 705f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 706f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 707f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 708f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 709f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 710f04d5140SColin Leitner }; 711f04d5140SColin Leitner 712d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = { 713d902f472SFrank Praznik POWER_SUPPLY_PROP_PRESENT, 714d902f472SFrank Praznik POWER_SUPPLY_PROP_CAPACITY, 715d902f472SFrank Praznik POWER_SUPPLY_PROP_SCOPE, 716d902f472SFrank Praznik POWER_SUPPLY_PROP_STATUS, 717d902f472SFrank Praznik }; 718d902f472SFrank Praznik 719cc6e0bbbSJiri Kosina struct sony_sc { 720d902f472SFrank Praznik spinlock_t lock; 7210a286ef2SSven Eckelmann struct hid_device *hdev; 72260781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 723cc6e0bbbSJiri Kosina unsigned long quirks; 7240a286ef2SSven Eckelmann struct work_struct state_worker; 725d902f472SFrank Praznik struct power_supply battery; 726f04d5140SColin Leitner 7279f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 7289f323b68SSven Eckelmann __u8 left; 7299f323b68SSven Eckelmann __u8 right; 7309f323b68SSven Eckelmann #endif 7319f323b68SSven Eckelmann 732d902f472SFrank Praznik __u8 cable_state; 733d902f472SFrank Praznik __u8 battery_charging; 734d902f472SFrank Praznik __u8 battery_capacity; 73560781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 73660781cf4SFrank Praznik __u8 led_count; 737cc6e0bbbSJiri Kosina }; 738cc6e0bbbSJiri Kosina 739078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 740078328daSJiri Kosina unsigned int *rsize) 741078328daSJiri Kosina { 742078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 743078328daSJiri Kosina return ps3remote_rdesc; 744078328daSJiri Kosina } 745078328daSJiri Kosina 746078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 747078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 748078328daSJiri Kosina unsigned long **bit, int *max) 749078328daSJiri Kosina { 750078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 751078328daSJiri Kosina 752078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 753078328daSJiri Kosina return -1; 754078328daSJiri Kosina 755078328daSJiri Kosina switch (usage->collection_index) { 756078328daSJiri Kosina case 1: 757078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 758078328daSJiri Kosina return -1; 759078328daSJiri Kosina 760078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 761078328daSJiri Kosina if (!key) 762078328daSJiri Kosina return -1; 763078328daSJiri Kosina break; 764078328daSJiri Kosina case 2: 765078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 766078328daSJiri Kosina return -1; 767078328daSJiri Kosina 768078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 769078328daSJiri Kosina if (!key) 770078328daSJiri Kosina return -1; 771078328daSJiri Kosina break; 772078328daSJiri Kosina default: 773078328daSJiri Kosina return -1; 774078328daSJiri Kosina } 775078328daSJiri Kosina 776078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 777078328daSJiri Kosina return 1; 778078328daSJiri Kosina } 779078328daSJiri Kosina 780078328daSJiri Kosina 781cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 78273e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 78373e4008dSNikolai Kondrashov unsigned int *rsize) 784cc6e0bbbSJiri Kosina { 785cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 786cc6e0bbbSJiri Kosina 78799d24902SFernando Luis Vázquez Cao /* 78899d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 78999d24902SFernando Luis Vázquez Cao * a constant non-data variable. 79099d24902SFernando Luis Vázquez Cao */ 79199d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 79299d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 79399d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 79499d24902SFernando Luis Vázquez Cao /* usage: mouse */ 79599d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 79699d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 79799d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 798a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 79999d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 800cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 801cc6e0bbbSJiri Kosina } 80261ab44beSSimon Wood 803ed19d8cfSFrank Praznik /* 804ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 805ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 806ed19d8cfSFrank Praznik * modified one. 807ed19d8cfSFrank Praznik */ 808ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 809ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 810ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 811ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 812d829674dSFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { 813d829674dSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); 814d829674dSFrank Praznik rdesc = dualshock4_bt_rdesc; 815d829674dSFrank Praznik *rsize = sizeof(dualshock4_bt_rdesc); 816ed19d8cfSFrank Praznik } 817ed19d8cfSFrank Praznik 81861ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 81961ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 82061ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 82161ab44beSSimon Wood rdesc[83] == 0x75) { 82261ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 82361ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 82461ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 825e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 826e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 827e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 828e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 829e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 830e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 83161ab44beSSimon Wood } 832078328daSJiri Kosina 833078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 834078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 835078328daSJiri Kosina 83673e4008dSNikolai Kondrashov return rdesc; 837cc6e0bbbSJiri Kosina } 838cc6e0bbbSJiri Kosina 839d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) 840d902f472SFrank Praznik { 841d902f472SFrank Praznik static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 842d902f472SFrank Praznik unsigned long flags; 843d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 844d902f472SFrank Praznik 845*ad142b9eSFrank Praznik /* 846*ad142b9eSFrank Praznik * The sixaxis is charging if the battery value is 0xee 847d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 848d902f472SFrank Praznik * It does not report the actual level while charging so it 849d902f472SFrank Praznik * is set to 100% while charging is in progress. 850d902f472SFrank Praznik */ 851d902f472SFrank Praznik if (rd[30] >= 0xee) { 852d902f472SFrank Praznik battery_capacity = 100; 853a43e94a3SFrank Praznik battery_charging = !(rd[30] & 0x01); 854d902f472SFrank Praznik } else { 855d902f472SFrank Praznik battery_capacity = sixaxis_battery_capacity[rd[30]]; 856d902f472SFrank Praznik battery_charging = 0; 857d902f472SFrank Praznik } 858a43e94a3SFrank Praznik cable_state = !((rd[31] >> 4) & 0x01); 859d902f472SFrank Praznik 860d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 861d902f472SFrank Praznik sc->cable_state = cable_state; 862d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 863d902f472SFrank Praznik sc->battery_charging = battery_charging; 864d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 865d902f472SFrank Praznik } 866d902f472SFrank Praznik 867d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) 868d902f472SFrank Praznik { 869e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 870e5606230SFrank Praznik struct hid_input, list); 871e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 872d902f472SFrank Praznik unsigned long flags; 8736c5f860dSFrank Praznik int n, offset; 874d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 875d902f472SFrank Praznik 876*ad142b9eSFrank Praznik /* 877*ad142b9eSFrank Praznik * Battery and touchpad data starts at byte 30 in the USB report and 8786c5f860dSFrank Praznik * 32 in Bluetooth report. 8796c5f860dSFrank Praznik */ 8806c5f860dSFrank Praznik offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; 8816c5f860dSFrank Praznik 882*ad142b9eSFrank Praznik /* 883*ad142b9eSFrank Praznik * The lower 4 bits of byte 30 contain the battery level 884d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 885d902f472SFrank Praznik */ 8866c5f860dSFrank Praznik cable_state = (rd[offset] >> 4) & 0x01; 8876c5f860dSFrank Praznik battery_capacity = rd[offset] & 0x0F; 888d902f472SFrank Praznik 889*ad142b9eSFrank Praznik /* 890*ad142b9eSFrank Praznik * When a USB power source is connected the battery level ranges from 8916c5f860dSFrank Praznik * 0 to 10, and when running on battery power it ranges from 0 to 9. 8926c5f860dSFrank Praznik * A battery level above 10 when plugged in means charge completed. 893d902f472SFrank Praznik */ 8946c5f860dSFrank Praznik if (!cable_state || battery_capacity > 10) 895d902f472SFrank Praznik battery_charging = 0; 896d902f472SFrank Praznik else 897d902f472SFrank Praznik battery_charging = 1; 898d902f472SFrank Praznik 8996c5f860dSFrank Praznik if (!cable_state) 9006c5f860dSFrank Praznik battery_capacity++; 901d902f472SFrank Praznik if (battery_capacity > 10) 9026c5f860dSFrank Praznik battery_capacity = 10; 9036c5f860dSFrank Praznik 904d902f472SFrank Praznik battery_capacity *= 10; 905d902f472SFrank Praznik 906d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 907d902f472SFrank Praznik sc->cable_state = cable_state; 908d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 909d902f472SFrank Praznik sc->battery_charging = battery_charging; 910d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 911e5606230SFrank Praznik 9126c5f860dSFrank Praznik offset += 5; 9136c5f860dSFrank Praznik 914*ad142b9eSFrank Praznik /* 915*ad142b9eSFrank Praznik * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB 9166c5f860dSFrank Praznik * and 37 on Bluetooth. 917e5606230SFrank Praznik * The first 7 bits of the first byte is a counter and bit 8 is a touch 918e5606230SFrank Praznik * indicator that is 0 when pressed and 1 when not pressed. 919e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 920e5606230SFrank Praznik * The data for the second touch is in the same format and immediatly 921e5606230SFrank Praznik * follows the data for the first. 922e5606230SFrank Praznik */ 923e5606230SFrank Praznik for (n = 0; n < 2; n++) { 924e5606230SFrank Praznik __u16 x, y; 925e5606230SFrank Praznik 926e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 927e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 928e5606230SFrank Praznik 929e5606230SFrank Praznik input_mt_slot(input_dev, n); 930e5606230SFrank Praznik input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 931e5606230SFrank Praznik !(rd[offset] >> 7)); 932e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_X, x); 933e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 934e5606230SFrank Praznik 935e5606230SFrank Praznik offset += 4; 936e5606230SFrank Praznik } 937d902f472SFrank Praznik } 938d902f472SFrank Praznik 939c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 940c9e4d877SSimon Wood __u8 *rd, int size) 941c9e4d877SSimon Wood { 942c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 943c9e4d877SSimon Wood 944*ad142b9eSFrank Praznik /* 945*ad142b9eSFrank Praznik * Sixaxis HID report has acclerometers/gyro with MSByte first, this 946c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 947c9e4d877SSimon Wood */ 948fee4e2d5SFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { 949c9e4d877SSimon Wood swap(rd[41], rd[42]); 950c9e4d877SSimon Wood swap(rd[43], rd[44]); 951c9e4d877SSimon Wood swap(rd[45], rd[46]); 952c9e4d877SSimon Wood swap(rd[47], rd[48]); 953d902f472SFrank Praznik 954d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 95568330d83SFrank Praznik } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 95668330d83SFrank Praznik size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) 95768330d83SFrank Praznik && rd[0] == 0x11 && size == 78)) { 958d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 959c9e4d877SSimon Wood } 960c9e4d877SSimon Wood 961c9e4d877SSimon Wood return 0; 962c9e4d877SSimon Wood } 963c9e4d877SSimon Wood 964f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 965f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 966f04d5140SColin Leitner unsigned long **bit, int *max) 967f04d5140SColin Leitner { 968f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 969f04d5140SColin Leitner 970f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 971f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 972f04d5140SColin Leitner 973f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 974f04d5140SColin Leitner return -1; 975f04d5140SColin Leitner 976f04d5140SColin Leitner switch (usage->collection_index) { 977f04d5140SColin Leitner case 1: 978f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 979f04d5140SColin Leitner return -1; 980f04d5140SColin Leitner 981f04d5140SColin Leitner key = buzz_keymap[key]; 982f04d5140SColin Leitner if (!key) 983f04d5140SColin Leitner return -1; 984f04d5140SColin Leitner break; 985f04d5140SColin Leitner default: 986f04d5140SColin Leitner return -1; 987f04d5140SColin Leitner } 988f04d5140SColin Leitner 989f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 990f04d5140SColin Leitner return 1; 991f04d5140SColin Leitner } 992f04d5140SColin Leitner 993078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 994078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 995078328daSJiri Kosina 9966f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 9976f498018SBenjamin Tissoires return 0; 998f04d5140SColin Leitner } 999f04d5140SColin Leitner 10005710fabfSAntonio Ospite /* 10015710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 10025710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 10035710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 10045710fabfSAntonio Ospite * 10055710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 10065710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 10075710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 10085710fabfSAntonio Ospite * reports, humpf! 10095710fabfSAntonio Ospite */ 1010569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 1011569b10a5SAntonio Ospite size_t count, unsigned char report_type) 1012569b10a5SAntonio Ospite { 1013569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 1014569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 1015569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 1016569b10a5SAntonio Ospite int report_id = buf[0]; 1017569b10a5SAntonio Ospite int ret; 1018569b10a5SAntonio Ospite 10195710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 10205710fabfSAntonio Ospite /* Don't send the Report ID */ 10215710fabfSAntonio Ospite buf++; 10225710fabfSAntonio Ospite count--; 10235710fabfSAntonio Ospite } 10245710fabfSAntonio Ospite 1025569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1026569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 1027569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 1028569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 1029569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 1030569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 1031569b10a5SAntonio Ospite 10325710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 10335710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 10345710fabfSAntonio Ospite ret++; 10355710fabfSAntonio Ospite 1036569b10a5SAntonio Ospite return ret; 1037569b10a5SAntonio Ospite } 1038569b10a5SAntonio Ospite 1039bd28ce00SJiri Slaby /* 1040bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1041bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1042bd28ce00SJiri Slaby * events. 1043bd28ce00SJiri Slaby */ 1044816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1045bd28ce00SJiri Slaby { 1046bd28ce00SJiri Slaby int ret; 1047bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 1048bd28ce00SJiri Slaby 1049bd28ce00SJiri Slaby if (!buf) 1050bd28ce00SJiri Slaby return -ENOMEM; 1051bd28ce00SJiri Slaby 1052cafebc05SBenjamin Tissoires ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1053cafebc05SBenjamin Tissoires HID_REQ_GET_REPORT); 1054f204828aSBenjamin Tissoires 1055bd28ce00SJiri Slaby if (ret < 0) 10564291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 1057bd28ce00SJiri Slaby 1058bd28ce00SJiri Slaby kfree(buf); 1059bd28ce00SJiri Slaby 1060bd28ce00SJiri Slaby return ret; 1061bd28ce00SJiri Slaby } 1062bd28ce00SJiri Slaby 1063816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1064f9ce7c28SBastien Nocera { 1065fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 10667e845d46SBenjamin Tissoires return hid_output_raw_report(hdev, buf, sizeof(buf), 10677e845d46SBenjamin Tissoires HID_FEATURE_REPORT); 1068f9ce7c28SBastien Nocera } 1069f9ce7c28SBastien Nocera 1070*ad142b9eSFrank Praznik /* 1071*ad142b9eSFrank Praznik * Requesting feature report 0x02 in Bluetooth mode changes the state of the 107268330d83SFrank Praznik * controller so that it sends full input reports of type 0x11. 107368330d83SFrank Praznik */ 107468330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev) 107568330d83SFrank Praznik { 107668330d83SFrank Praznik __u8 buf[37] = { 0 }; 107768330d83SFrank Praznik 107868330d83SFrank Praznik return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), 107968330d83SFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 108068330d83SFrank Praznik } 108168330d83SFrank Praznik 108260781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 1083f04d5140SColin Leitner { 1084f04d5140SColin Leitner struct list_head *report_list = 1085f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1086f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1087f04d5140SColin Leitner struct hid_report, list); 1088f04d5140SColin Leitner __s32 *value = report->field[0]->value; 1089f04d5140SColin Leitner 1090f04d5140SColin Leitner value[0] = 0x00; 109160781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 109260781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 109360781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 109460781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 1095f04d5140SColin Leitner value[5] = 0x00; 1096f04d5140SColin Leitner value[6] = 0x00; 1097f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1098f04d5140SColin Leitner } 1099f04d5140SColin Leitner 110060781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) 11010a286ef2SSven Eckelmann { 11020a286ef2SSven Eckelmann struct sony_sc *drv_data = hid_get_drvdata(hdev); 110360781cf4SFrank Praznik int n; 11040a286ef2SSven Eckelmann 110560781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 110660781cf4SFrank Praznik 110760781cf4SFrank Praznik if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { 11080a286ef2SSven Eckelmann buzz_set_leds(hdev, leds); 1109fee4e2d5SFrank Praznik } else { 111060781cf4SFrank Praznik for (n = 0; n < count; n++) 111160781cf4SFrank Praznik drv_data->led_state[n] = leds[n]; 11120a286ef2SSven Eckelmann schedule_work(&drv_data->state_worker); 11130a286ef2SSven Eckelmann } 11140a286ef2SSven Eckelmann } 11150a286ef2SSven Eckelmann 1116c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1117f04d5140SColin Leitner enum led_brightness value) 1118f04d5140SColin Leitner { 1119f04d5140SColin Leitner struct device *dev = led->dev->parent; 1120f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1121f04d5140SColin Leitner struct sony_sc *drv_data; 1122f04d5140SColin Leitner 1123f04d5140SColin Leitner int n; 1124f04d5140SColin Leitner 1125f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 11262251b85fSSven Eckelmann if (!drv_data) { 1127f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1128f04d5140SColin Leitner return; 1129f04d5140SColin Leitner } 1130f04d5140SColin Leitner 113160781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 11322251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 113360781cf4SFrank Praznik if (value != drv_data->led_state[n]) { 113460781cf4SFrank Praznik drv_data->led_state[n] = value; 113560781cf4SFrank Praznik sony_set_leds(hdev, drv_data->led_state, drv_data->led_count); 1136f04d5140SColin Leitner } 1137f04d5140SColin Leitner break; 1138f04d5140SColin Leitner } 1139f04d5140SColin Leitner } 1140f04d5140SColin Leitner } 1141f04d5140SColin Leitner 1142c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1143f04d5140SColin Leitner { 1144f04d5140SColin Leitner struct device *dev = led->dev->parent; 1145f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1146f04d5140SColin Leitner struct sony_sc *drv_data; 1147f04d5140SColin Leitner 1148f04d5140SColin Leitner int n; 1149f04d5140SColin Leitner 1150f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 11512251b85fSSven Eckelmann if (!drv_data) { 1152f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1153f04d5140SColin Leitner return LED_OFF; 1154f04d5140SColin Leitner } 1155f04d5140SColin Leitner 115660781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 11577db7504aSSimon Wood if (led == drv_data->leds[n]) 11587db7504aSSimon Wood return drv_data->led_state[n]; 1159f04d5140SColin Leitner } 1160f04d5140SColin Leitner 11617db7504aSSimon Wood return LED_OFF; 1162f04d5140SColin Leitner } 1163f04d5140SColin Leitner 11640a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev) 11650a286ef2SSven Eckelmann { 11660a286ef2SSven Eckelmann struct sony_sc *drv_data; 11670a286ef2SSven Eckelmann struct led_classdev *led; 11680a286ef2SSven Eckelmann int n; 11690a286ef2SSven Eckelmann 11700a286ef2SSven Eckelmann drv_data = hid_get_drvdata(hdev); 11710a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 11720a286ef2SSven Eckelmann 117360781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 11740a286ef2SSven Eckelmann led = drv_data->leds[n]; 11750a286ef2SSven Eckelmann drv_data->leds[n] = NULL; 11760a286ef2SSven Eckelmann if (!led) 11770a286ef2SSven Eckelmann continue; 11780a286ef2SSven Eckelmann led_classdev_unregister(led); 11790a286ef2SSven Eckelmann kfree(led); 11800a286ef2SSven Eckelmann } 118160781cf4SFrank Praznik 118260781cf4SFrank Praznik drv_data->led_count = 0; 11830a286ef2SSven Eckelmann } 11840a286ef2SSven Eckelmann 1185c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev) 1186f04d5140SColin Leitner { 1187f04d5140SColin Leitner struct sony_sc *drv_data; 118840e32ee6SJiri Kosina int n, ret = 0; 118960781cf4SFrank Praznik int max_brightness; 119061ebca93SFrank Praznik int use_colors; 119140e32ee6SJiri Kosina struct led_classdev *led; 119240e32ee6SJiri Kosina size_t name_sz; 119340e32ee6SJiri Kosina char *name; 11940a286ef2SSven Eckelmann size_t name_len; 11950a286ef2SSven Eckelmann const char *name_fmt; 119661ebca93SFrank Praznik static const char * const color_str[] = { "red", "green", "blue" }; 119760781cf4SFrank Praznik static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 }; 1198f04d5140SColin Leitner 1199f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12000a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 1201f04d5140SColin Leitner 12020a286ef2SSven Eckelmann if (drv_data->quirks & BUZZ_CONTROLLER) { 120361ebca93SFrank Praznik drv_data->led_count = 4; 120461ebca93SFrank Praznik max_brightness = 1; 120561ebca93SFrank Praznik use_colors = 0; 12060a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 12070a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 12089446edb9SKees Cook /* Validate expected report characteristics. */ 12099446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 12109446edb9SKees Cook return -ENODEV; 121168330d83SFrank Praznik } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER) { 121260781cf4SFrank Praznik drv_data->led_count = 3; 121360781cf4SFrank Praznik max_brightness = 255; 121461ebca93SFrank Praznik use_colors = 1; 121561ebca93SFrank Praznik name_len = 0; 121661ebca93SFrank Praznik name_fmt = "%s:%s"; 121760781cf4SFrank Praznik } else { 121860781cf4SFrank Praznik drv_data->led_count = 4; 121960781cf4SFrank Praznik max_brightness = 1; 122061ebca93SFrank Praznik use_colors = 0; 122161ebca93SFrank Praznik name_len = strlen("::sony#"); 122261ebca93SFrank Praznik name_fmt = "%s::sony%d"; 122360781cf4SFrank Praznik } 122460781cf4SFrank Praznik 1225*ad142b9eSFrank Praznik /* 1226*ad142b9eSFrank Praznik * Clear LEDs as we have no way of reading their initial state. This is 1227f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1228*ad142b9eSFrank Praznik * LEDs to on 1229*ad142b9eSFrank Praznik */ 123060781cf4SFrank Praznik sony_set_leds(hdev, initial_values, drv_data->led_count); 1231f04d5140SColin Leitner 12320a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1233f04d5140SColin Leitner 123460781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 123561ebca93SFrank Praznik 123661ebca93SFrank Praznik if (use_colors) 123761ebca93SFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2; 123861ebca93SFrank Praznik 1239f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1240f04d5140SColin Leitner if (!led) { 1241f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 12428cd5fcdaSJulia Lawall ret = -ENOMEM; 1243f04d5140SColin Leitner goto error_leds; 1244f04d5140SColin Leitner } 1245f04d5140SColin Leitner 1246f04d5140SColin Leitner name = (void *)(&led[1]); 124761ebca93SFrank Praznik if (use_colors) 124861ebca93SFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_str[n]); 124961ebca93SFrank Praznik else 12500a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1251f04d5140SColin Leitner led->name = name; 1252f04d5140SColin Leitner led->brightness = 0; 125360781cf4SFrank Praznik led->max_brightness = max_brightness; 1254c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1255c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1256f04d5140SColin Leitner 12578cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 12588cd5fcdaSJulia Lawall if (ret) { 1259f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 1260f04d5140SColin Leitner kfree(led); 1261f04d5140SColin Leitner goto error_leds; 1262f04d5140SColin Leitner } 1263f04d5140SColin Leitner 12642251b85fSSven Eckelmann drv_data->leds[n] = led; 1265f04d5140SColin Leitner } 1266f04d5140SColin Leitner 1267f04d5140SColin Leitner return ret; 1268f04d5140SColin Leitner 1269f04d5140SColin Leitner error_leds: 12700a286ef2SSven Eckelmann sony_leds_remove(hdev); 1271f04d5140SColin Leitner 1272f04d5140SColin Leitner return ret; 1273f04d5140SColin Leitner } 1274f04d5140SColin Leitner 1275cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 1276a08c22c0SSven Eckelmann { 127792b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1278a08c22c0SSven Eckelmann unsigned char buf[] = { 1279a08c22c0SSven Eckelmann 0x01, 1280a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 12810a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1282a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1283a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1284a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1285a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1286a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 1287a08c22c0SSven Eckelmann }; 12889f323b68SSven Eckelmann 12890a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 12900bd88dd3SFrank Praznik buf[3] = sc->right ? 1 : 0; 12919f323b68SSven Eckelmann buf[5] = sc->left; 12920a286ef2SSven Eckelmann #endif 12930a286ef2SSven Eckelmann 129460781cf4SFrank Praznik buf[10] |= sc->led_state[0] << 1; 129560781cf4SFrank Praznik buf[10] |= sc->led_state[1] << 2; 129660781cf4SFrank Praznik buf[10] |= sc->led_state[2] << 3; 129760781cf4SFrank Praznik buf[10] |= sc->led_state[3] << 4; 12989f323b68SSven Eckelmann 1299fee4e2d5SFrank Praznik if (sc->quirks & SIXAXIS_CONTROLLER_USB) 13007e845d46SBenjamin Tissoires hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT); 1301fee4e2d5SFrank Praznik else 1302fee4e2d5SFrank Praznik hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf), 1303fee4e2d5SFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 13049f323b68SSven Eckelmann } 13059f323b68SSven Eckelmann 13060bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 13070bd88dd3SFrank Praznik { 13080bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 13090da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 131048220237SFrank Praznik int offset; 13110da8ea65SFrank Praznik 1312fdcf105dSFrank Praznik __u8 buf[78] = { 0 }; 131348220237SFrank Praznik 1314fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 131548220237SFrank Praznik buf[0] = 0x05; 131648220237SFrank Praznik buf[1] = 0x03; 131748220237SFrank Praznik offset = 4; 1318fdcf105dSFrank Praznik } else { 1319fdcf105dSFrank Praznik buf[0] = 0x11; 1320fdcf105dSFrank Praznik buf[1] = 0xB0; 1321fdcf105dSFrank Praznik buf[3] = 0x0F; 1322fdcf105dSFrank Praznik offset = 6; 1323fdcf105dSFrank Praznik } 13240bd88dd3SFrank Praznik 13250bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 132648220237SFrank Praznik buf[offset++] = sc->right; 132748220237SFrank Praznik buf[offset++] = sc->left; 132848220237SFrank Praznik #else 132948220237SFrank Praznik offset += 2; 13300bd88dd3SFrank Praznik #endif 13310bd88dd3SFrank Praznik 133248220237SFrank Praznik buf[offset++] = sc->led_state[0]; 133348220237SFrank Praznik buf[offset++] = sc->led_state[1]; 133448220237SFrank Praznik buf[offset++] = sc->led_state[2]; 133560781cf4SFrank Praznik 1336fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1337fdcf105dSFrank Praznik hid_hw_output_report(hdev, buf, 32); 1338fdcf105dSFrank Praznik else 1339fdcf105dSFrank Praznik hid_hw_raw_request(hdev, 0x11, buf, 78, 1340fdcf105dSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 13410bd88dd3SFrank Praznik } 13420bd88dd3SFrank Praznik 13430a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 13449f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 13459f323b68SSven Eckelmann struct ff_effect *effect) 13469f323b68SSven Eckelmann { 1347a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 13489f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 1349a08c22c0SSven Eckelmann 1350a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 1351a08c22c0SSven Eckelmann return 0; 1352a08c22c0SSven Eckelmann 13539f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 13540bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 1355a08c22c0SSven Eckelmann 135692b5c411SSven Eckelmann schedule_work(&sc->state_worker); 13579f323b68SSven Eckelmann return 0; 1358a08c22c0SSven Eckelmann } 1359a08c22c0SSven Eckelmann 1360a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 1361a08c22c0SSven Eckelmann { 1362a08c22c0SSven Eckelmann struct hid_input *hidinput = list_entry(hdev->inputs.next, 1363a08c22c0SSven Eckelmann struct hid_input, list); 1364a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 1365a08c22c0SSven Eckelmann 1366a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 1367a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 1368a08c22c0SSven Eckelmann } 1369a08c22c0SSven Eckelmann 13709f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 13719f323b68SSven Eckelmann { 13729f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hdev); 13739f323b68SSven Eckelmann 137492b5c411SSven Eckelmann cancel_work_sync(&sc->state_worker); 13759f323b68SSven Eckelmann } 13769f323b68SSven Eckelmann 1377a08c22c0SSven Eckelmann #else 1378a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 1379a08c22c0SSven Eckelmann { 1380a08c22c0SSven Eckelmann return 0; 1381a08c22c0SSven Eckelmann } 13829f323b68SSven Eckelmann 13839f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 13849f323b68SSven Eckelmann { 13859f323b68SSven Eckelmann } 1386a08c22c0SSven Eckelmann #endif 1387a08c22c0SSven Eckelmann 1388d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 1389d902f472SFrank Praznik enum power_supply_property psp, 1390d902f472SFrank Praznik union power_supply_propval *val) 1391d902f472SFrank Praznik { 1392d902f472SFrank Praznik struct sony_sc *sc = container_of(psy, struct sony_sc, battery); 1393d902f472SFrank Praznik unsigned long flags; 1394d902f472SFrank Praznik int ret = 0; 1395d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 1396d902f472SFrank Praznik 1397d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 1398d902f472SFrank Praznik battery_charging = sc->battery_charging; 1399d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 1400d902f472SFrank Praznik cable_state = sc->cable_state; 1401d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 1402d902f472SFrank Praznik 1403d902f472SFrank Praznik switch (psp) { 1404d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 1405d902f472SFrank Praznik val->intval = 1; 1406d902f472SFrank Praznik break; 1407d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 1408d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 1409d902f472SFrank Praznik break; 1410d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 1411d902f472SFrank Praznik val->intval = battery_capacity; 1412d902f472SFrank Praznik break; 1413d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 1414d902f472SFrank Praznik if (battery_charging) 1415d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 1416d902f472SFrank Praznik else 1417d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 1418d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 1419d902f472SFrank Praznik else 1420d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1421d902f472SFrank Praznik break; 1422d902f472SFrank Praznik default: 1423d902f472SFrank Praznik ret = -EINVAL; 1424d902f472SFrank Praznik break; 1425d902f472SFrank Praznik } 1426d902f472SFrank Praznik return ret; 1427d902f472SFrank Praznik } 1428d902f472SFrank Praznik 1429d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc) 1430d902f472SFrank Praznik { 1431d902f472SFrank Praznik static atomic_t power_id_seq = ATOMIC_INIT(0); 1432d902f472SFrank Praznik unsigned long power_id; 1433d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 1434d902f472SFrank Praznik int ret; 1435d902f472SFrank Praznik 1436*ad142b9eSFrank Praznik /* 1437*ad142b9eSFrank Praznik * Set the default battery level to 100% to avoid low battery warnings 1438d9a293a9SFrank Praznik * if the battery is polled before the first device report is received. 1439d9a293a9SFrank Praznik */ 1440d9a293a9SFrank Praznik sc->battery_capacity = 100; 1441d9a293a9SFrank Praznik 1442d902f472SFrank Praznik power_id = (unsigned long)atomic_inc_return(&power_id_seq); 1443d902f472SFrank Praznik 1444d902f472SFrank Praznik sc->battery.properties = sony_battery_props; 1445d902f472SFrank Praznik sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); 1446d902f472SFrank Praznik sc->battery.get_property = sony_battery_get_property; 1447d902f472SFrank Praznik sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; 1448d902f472SFrank Praznik sc->battery.use_for_apm = 0; 1449d902f472SFrank Praznik sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu", 1450d902f472SFrank Praznik power_id); 1451d902f472SFrank Praznik if (!sc->battery.name) 1452d902f472SFrank Praznik return -ENOMEM; 1453d902f472SFrank Praznik 1454d902f472SFrank Praznik ret = power_supply_register(&hdev->dev, &sc->battery); 1455d902f472SFrank Praznik if (ret) { 1456d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 1457d902f472SFrank Praznik goto err_free; 1458d902f472SFrank Praznik } 1459d902f472SFrank Praznik 1460d902f472SFrank Praznik power_supply_powers(&sc->battery, &hdev->dev); 1461d902f472SFrank Praznik return 0; 1462d902f472SFrank Praznik 1463d902f472SFrank Praznik err_free: 1464d902f472SFrank Praznik kfree(sc->battery.name); 1465d902f472SFrank Praznik sc->battery.name = NULL; 1466d902f472SFrank Praznik return ret; 1467d902f472SFrank Praznik } 1468d902f472SFrank Praznik 1469d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 1470d902f472SFrank Praznik { 1471d902f472SFrank Praznik if (!sc->battery.name) 1472d902f472SFrank Praznik return; 1473d902f472SFrank Praznik 1474d902f472SFrank Praznik power_supply_unregister(&sc->battery); 1475d902f472SFrank Praznik kfree(sc->battery.name); 1476d902f472SFrank Praznik sc->battery.name = NULL; 1477d902f472SFrank Praznik } 1478d902f472SFrank Praznik 1479e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1480e5606230SFrank Praznik int w, int h) 1481e5606230SFrank Praznik { 1482e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1483e5606230SFrank Praznik struct hid_input, list); 1484e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 1485e5606230SFrank Praznik int ret; 1486e5606230SFrank Praznik 1487e5606230SFrank Praznik ret = input_mt_init_slots(input_dev, touch_count, 0); 1488e5606230SFrank Praznik if (ret < 0) { 1489e5606230SFrank Praznik hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); 1490e5606230SFrank Praznik return ret; 1491e5606230SFrank Praznik } 1492e5606230SFrank Praznik 1493e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); 1494e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); 1495e5606230SFrank Praznik 1496e5606230SFrank Praznik return 0; 1497e5606230SFrank Praznik } 1498e5606230SFrank Praznik 1499bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1500bd28ce00SJiri Slaby { 1501bd28ce00SJiri Slaby int ret; 1502cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1503cc6e0bbbSJiri Kosina struct sony_sc *sc; 1504f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1505cc6e0bbbSJiri Kosina 1506abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1507cc6e0bbbSJiri Kosina if (sc == NULL) { 15084291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1509cc6e0bbbSJiri Kosina return -ENOMEM; 1510cc6e0bbbSJiri Kosina } 1511cc6e0bbbSJiri Kosina 1512cc6e0bbbSJiri Kosina sc->quirks = quirks; 1513cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 15140a286ef2SSven Eckelmann sc->hdev = hdev; 1515bd28ce00SJiri Slaby 1516bd28ce00SJiri Slaby ret = hid_parse(hdev); 1517bd28ce00SJiri Slaby if (ret) { 15184291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1519abf832bfSBenjamin Tissoires return ret; 1520bd28ce00SJiri Slaby } 1521bd28ce00SJiri Slaby 1522f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1523f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1524f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 1525f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1526f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 1527f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1528f04d5140SColin Leitner 1529f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1530bd28ce00SJiri Slaby if (ret) { 15314291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1532abf832bfSBenjamin Tissoires return ret; 1533bd28ce00SJiri Slaby } 1534bd28ce00SJiri Slaby 1535569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1536569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 1537816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 1538cad665a2SFrank Praznik INIT_WORK(&sc->state_worker, sixaxis_state_worker); 1539fee4e2d5SFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) { 1540816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 1541fee4e2d5SFrank Praznik INIT_WORK(&sc->state_worker, sixaxis_state_worker); 1542fee4e2d5SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 154368330d83SFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { 154468330d83SFrank Praznik ret = dualshock4_set_operational_bt(hdev); 154568330d83SFrank Praznik if (ret < 0) { 154668330d83SFrank Praznik hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); 154768330d83SFrank Praznik goto err_stop; 154868330d83SFrank Praznik } 154968330d83SFrank Praznik } 1550*ad142b9eSFrank Praznik /* 1551*ad142b9eSFrank Praznik * The Dualshock 4 touchpad supports 2 touches and has a 1552e5606230SFrank Praznik * resolution of 1920x940. 1553e5606230SFrank Praznik */ 1554e5606230SFrank Praznik ret = sony_register_touchpad(sc, 2, 1920, 940); 1555e5606230SFrank Praznik if (ret < 0) 1556e5606230SFrank Praznik goto err_stop; 1557e5606230SFrank Praznik 15580bd88dd3SFrank Praznik INIT_WORK(&sc->state_worker, dualshock4_state_worker); 15590bd88dd3SFrank Praznik } else { 15600bd88dd3SFrank Praznik ret = 0; 15610bd88dd3SFrank Praznik } 1562f9ce7c28SBastien Nocera 15634dfdc464SJiri Kosina if (ret < 0) 1564bd28ce00SJiri Slaby goto err_stop; 1565bd28ce00SJiri Slaby 15660a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 15670a286ef2SSven Eckelmann ret = sony_leds_init(hdev); 15680a286ef2SSven Eckelmann if (ret < 0) 15690a286ef2SSven Eckelmann goto err_stop; 15700a286ef2SSven Eckelmann } 15710a286ef2SSven Eckelmann 1572d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1573d902f472SFrank Praznik ret = sony_battery_probe(sc); 1574a08c22c0SSven Eckelmann if (ret < 0) 1575a08c22c0SSven Eckelmann goto err_stop; 1576a08c22c0SSven Eckelmann 1577d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 1578d902f472SFrank Praznik ret = hid_hw_open(hdev); 1579d902f472SFrank Praznik if (ret < 0) { 1580d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 1581d902f472SFrank Praznik goto err_stop; 1582d902f472SFrank Praznik } 1583d902f472SFrank Praznik } 1584d902f472SFrank Praznik 1585d902f472SFrank Praznik ret = sony_init_ff(hdev); 1586d902f472SFrank Praznik if (ret < 0) 1587d902f472SFrank Praznik goto err_close; 1588d902f472SFrank Praznik 1589bd28ce00SJiri Slaby return 0; 1590d902f472SFrank Praznik err_close: 1591d902f472SFrank Praznik hid_hw_close(hdev); 1592bd28ce00SJiri Slaby err_stop: 15930a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 15940a286ef2SSven Eckelmann sony_leds_remove(hdev); 1595d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 1596d902f472SFrank Praznik sony_battery_remove(sc); 1597bd28ce00SJiri Slaby hid_hw_stop(hdev); 1598bd28ce00SJiri Slaby return ret; 1599bd28ce00SJiri Slaby } 1600bd28ce00SJiri Slaby 1601cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 1602cc6e0bbbSJiri Kosina { 1603f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1604f04d5140SColin Leitner 16050a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1606c5382519SSven Eckelmann sony_leds_remove(hdev); 1607f04d5140SColin Leitner 1608d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1609d902f472SFrank Praznik hid_hw_close(hdev); 1610d902f472SFrank Praznik sony_battery_remove(sc); 1611d902f472SFrank Praznik } 1612d902f472SFrank Praznik 16139f323b68SSven Eckelmann sony_destroy_ff(hdev); 16149f323b68SSven Eckelmann 1615cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 1616cc6e0bbbSJiri Kosina } 1617cc6e0bbbSJiri Kosina 1618bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 1619816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1620816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 162135dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 162235dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 1623816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1624816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 1625cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 1626cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 1627a4649184SFernando Luis Vázquez Cao { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 1628a4649184SFernando Luis Vázquez Cao .driver_data = VAIO_RDESC_CONSTANT }, 1629f04d5140SColin Leitner /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 1630f04d5140SColin Leitner * Logitech joystick from the device descriptor. */ 1631f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 1632f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1633f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 1634f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1635078328daSJiri Kosina /* PS3 BD Remote Control */ 1636078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 1637078328daSJiri Kosina .driver_data = PS3REMOTE }, 1638078328daSJiri Kosina /* Logitech Harmony Adapter for PS3 */ 1639078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 1640078328daSJiri Kosina .driver_data = PS3REMOTE }, 16410bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 16420bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 16438ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 16440bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 16458ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 1646bd28ce00SJiri Slaby { } 1647bd28ce00SJiri Slaby }; 1648bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 1649bd28ce00SJiri Slaby 1650bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 1651bd28ce00SJiri Slaby .name = "sony", 1652bd28ce00SJiri Slaby .id_table = sony_devices, 1653f04d5140SColin Leitner .input_mapping = sony_mapping, 1654bd28ce00SJiri Slaby .probe = sony_probe, 1655cc6e0bbbSJiri Kosina .remove = sony_remove, 1656cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 1657c9e4d877SSimon Wood .raw_event = sony_raw_event 1658bd28ce00SJiri Slaby }; 1659f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 1660bd28ce00SJiri Slaby 1661bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 1662