1bd28ce00SJiri Slaby /* 2078328daSJiri Kosina * HID driver for Sony / PS2 / PS3 BD devices. 3bd28ce00SJiri Slaby * 4bd28ce00SJiri Slaby * Copyright (c) 1999 Andreas Gal 5bd28ce00SJiri Slaby * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6bd28ce00SJiri Slaby * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7bd28ce00SJiri Slaby * Copyright (c) 2008 Jiri Slaby 8078328daSJiri Kosina * Copyright (c) 2012 David Dillow <dave@thedillows.org> 9078328daSJiri Kosina * Copyright (c) 2006-2013 Jiri Kosina 10f04d5140SColin Leitner * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> 11bd28ce00SJiri Slaby */ 12bd28ce00SJiri Slaby 13bd28ce00SJiri Slaby /* 14bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 15bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 16bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 17bd28ce00SJiri Slaby * any later version. 18bd28ce00SJiri Slaby */ 19bd28ce00SJiri Slaby 20078328daSJiri Kosina /* NOTE: in order for the Sony PS3 BD Remote Control to be found by 21078328daSJiri Kosina * a Bluetooth host, the key combination Start+Enter has to be kept pressed 22078328daSJiri Kosina * for about 7 seconds with the Bluetooth Host Controller in discovering mode. 23078328daSJiri Kosina * 24078328daSJiri Kosina * There will be no PIN request from the device. 25078328daSJiri Kosina */ 26078328daSJiri Kosina 27bd28ce00SJiri Slaby #include <linux/device.h> 28bd28ce00SJiri Slaby #include <linux/hid.h> 29bd28ce00SJiri Slaby #include <linux/module.h> 305a0e3ad6STejun Heo #include <linux/slab.h> 31bd28ce00SJiri Slaby #include <linux/usb.h> 3240e32ee6SJiri Kosina #include <linux/leds.h> 33d902f472SFrank Praznik #include <linux/power_supply.h> 34d902f472SFrank Praznik #include <linux/spinlock.h> 35e5606230SFrank Praznik #include <linux/input/mt.h> 36bd28ce00SJiri Slaby 37bd28ce00SJiri Slaby #include "hid-ids.h" 38bd28ce00SJiri Slaby 39f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 40f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 41f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 42f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 43f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 448ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 458ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 46cc6e0bbbSJiri Kosina 478ab1676bSFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) 48d902f472SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_USB) 4960781cf4SFrank Praznik 5060781cf4SFrank Praznik #define MAX_LEDS 4 510a286ef2SSven Eckelmann 5261ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 5361ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 5461ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 5561ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 5661ab44beSSimon Wood }; 5761ab44beSSimon Wood 58e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = { 59e57a67daSMauro Carvalho Chehab 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 60e57a67daSMauro Carvalho Chehab 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 61e57a67daSMauro Carvalho Chehab 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 62e57a67daSMauro Carvalho Chehab 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 63e57a67daSMauro Carvalho Chehab 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 64e57a67daSMauro Carvalho Chehab 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 65e57a67daSMauro Carvalho Chehab 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 66e57a67daSMauro Carvalho Chehab 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 67e57a67daSMauro Carvalho Chehab 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 68e57a67daSMauro Carvalho Chehab 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 69e57a67daSMauro Carvalho Chehab 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 70e57a67daSMauro Carvalho Chehab 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 71e57a67daSMauro Carvalho Chehab 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 72e57a67daSMauro Carvalho Chehab 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 73e57a67daSMauro Carvalho Chehab 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 74e57a67daSMauro Carvalho Chehab 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 75e57a67daSMauro Carvalho Chehab 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 76e57a67daSMauro Carvalho Chehab 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 77e57a67daSMauro Carvalho Chehab 0xb1, 0x02, 0xc0, 0xc0, 78e57a67daSMauro Carvalho Chehab }; 79e57a67daSMauro Carvalho Chehab 8058d7027bSFrank Praznik /* The default descriptor doesn't provide mapping for the accelerometers 8158d7027bSFrank Praznik * or orientation sensors. This fixed descriptor maps the accelerometers 8258d7027bSFrank Praznik * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors 8358d7027bSFrank Praznik * to usage values 0x43, 0x44 and 0x45. 8458d7027bSFrank Praznik */ 85ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = { 8658d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 8758d7027bSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 8858d7027bSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 8958d7027bSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 9058d7027bSFrank Praznik 0x09, 0x30, /* Usage (X), */ 9158d7027bSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 9258d7027bSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 9358d7027bSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 9458d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 9558d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 9658d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 9758d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 9858d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 9958d7027bSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 10058d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 10158d7027bSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 10258d7027bSFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 10358d7027bSFrank Praznik 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 10458d7027bSFrank Praznik 0x65, 0x14, /* Unit (Degrees), */ 10558d7027bSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 10658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 10758d7027bSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 10858d7027bSFrank Praznik 0x65, 0x00, /* Unit, */ 10958d7027bSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 11058d7027bSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 11158d7027bSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 11258d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 11358d7027bSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 11458d7027bSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 11558d7027bSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 11658d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 11758d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 11858d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 11958d7027bSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 12058d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 12158d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 12258d7027bSFrank Praznik 0x25, 0x7F, /* Logical Maximum (127), */ 12358d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 12458d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 12558d7027bSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 12658d7027bSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 12758d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 12858d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 12958d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 13058d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 13158d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 13258d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 13358d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 13458d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 13558d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 13658d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 13758d7027bSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 13858d7027bSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 13958d7027bSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 14058d7027bSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 14158d7027bSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 14258d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 14358d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 14458d7027bSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 14558d7027bSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 14658d7027bSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 14758d7027bSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 14858d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 14958d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15058d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 15158d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 15258d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 15358d7027bSFrank Praznik 0x25, 0xFF, /* Logical Maximum (255), */ 15458d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 15558d7027bSFrank Praznik 0x95, 0x27, /* Report Count (39), */ 15658d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15758d7027bSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 15858d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 15958d7027bSFrank Praznik 0x95, 0x1F, /* Report Count (31), */ 16058d7027bSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 16158d7027bSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 16258d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 16358d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 16458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 16558d7027bSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 16658d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 16758d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 16858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 16958d7027bSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 17058d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 17158d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 17258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17358d7027bSFrank Praznik 0x85, 0x10, /* Report ID (16), */ 17458d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 17558d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 17658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17758d7027bSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 17858d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 17958d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 18058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18158d7027bSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 18258d7027bSFrank Praznik 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ 18358d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 18458d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 18558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18658d7027bSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 18758d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 18858d7027bSFrank Praznik 0x95, 0x16, /* Report Count (22), */ 18958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19058d7027bSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 19158d7027bSFrank Praznik 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ 19258d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 19358d7027bSFrank Praznik 0x95, 0x10, /* Report Count (16), */ 19458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19558d7027bSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 19658d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 19758d7027bSFrank Praznik 0x95, 0x2C, /* Report Count (44), */ 19858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19958d7027bSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 20058d7027bSFrank Praznik 0x85, 0x80, /* Report ID (128), */ 20158d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 20258d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 20358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20458d7027bSFrank Praznik 0x85, 0x81, /* Report ID (129), */ 20558d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 20658d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 20758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20858d7027bSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 20958d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 21058d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 21158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21258d7027bSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 21358d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 21458d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 21558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21658d7027bSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 21758d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 21858d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 21958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22058d7027bSFrank Praznik 0x85, 0x85, /* Report ID (133), */ 22158d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 22258d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 22358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22458d7027bSFrank Praznik 0x85, 0x86, /* Report ID (134), */ 22558d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 22658d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 22758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22858d7027bSFrank Praznik 0x85, 0x87, /* Report ID (135), */ 22958d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 23058d7027bSFrank Praznik 0x95, 0x23, /* Report Count (35), */ 23158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23258d7027bSFrank Praznik 0x85, 0x88, /* Report ID (136), */ 23358d7027bSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 23458d7027bSFrank Praznik 0x95, 0x22, /* Report Count (34), */ 23558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23658d7027bSFrank Praznik 0x85, 0x89, /* Report ID (137), */ 23758d7027bSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 23858d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 23958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24058d7027bSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 24158d7027bSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 24258d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 24358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24458d7027bSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 24558d7027bSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 24658d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 24758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24858d7027bSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 24958d7027bSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 25058d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 25158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25258d7027bSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 25358d7027bSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 25458d7027bSFrank Praznik 0x95, 0x0C, /* Report Count (12), */ 25558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25658d7027bSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 25758d7027bSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 25858d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 25958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26058d7027bSFrank Praznik 0x85, 0xA1, /* Report ID (161), */ 26158d7027bSFrank Praznik 0x09, 0x41, /* Usage (41h), */ 26258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 26358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26458d7027bSFrank Praznik 0x85, 0xA2, /* Report ID (162), */ 26558d7027bSFrank Praznik 0x09, 0x42, /* Usage (42h), */ 26658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 26758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26858d7027bSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 26958d7027bSFrank Praznik 0x09, 0x43, /* Usage (43h), */ 27058d7027bSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 27158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27258d7027bSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 27358d7027bSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 27458d7027bSFrank Praznik 0x95, 0x0D, /* Report Count (13), */ 27558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27658d7027bSFrank Praznik 0x85, 0xA5, /* Report ID (165), */ 27758d7027bSFrank Praznik 0x09, 0x45, /* Usage (45h), */ 27858d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 27958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28058d7027bSFrank Praznik 0x85, 0xA6, /* Report ID (166), */ 28158d7027bSFrank Praznik 0x09, 0x46, /* Usage (46h), */ 28258d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 28358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28458d7027bSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 28558d7027bSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 28658d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 28758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28858d7027bSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 28958d7027bSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 29058d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 29158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29258d7027bSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 29358d7027bSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 29458d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 29558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29658d7027bSFrank Praznik 0x85, 0xA7, /* Report ID (167), */ 29758d7027bSFrank Praznik 0x09, 0x4A, /* Usage (4Ah), */ 29858d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 29958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30058d7027bSFrank Praznik 0x85, 0xA8, /* Report ID (168), */ 30158d7027bSFrank Praznik 0x09, 0x4B, /* Usage (4Bh), */ 30258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 30358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30458d7027bSFrank Praznik 0x85, 0xA9, /* Report ID (169), */ 30558d7027bSFrank Praznik 0x09, 0x4C, /* Usage (4Ch), */ 30658d7027bSFrank Praznik 0x95, 0x08, /* Report Count (8), */ 30758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30858d7027bSFrank Praznik 0x85, 0xAA, /* Report ID (170), */ 30958d7027bSFrank Praznik 0x09, 0x4E, /* Usage (4Eh), */ 31058d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 31158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31258d7027bSFrank Praznik 0x85, 0xAB, /* Report ID (171), */ 31358d7027bSFrank Praznik 0x09, 0x4F, /* Usage (4Fh), */ 31458d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 31558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31658d7027bSFrank Praznik 0x85, 0xAC, /* Report ID (172), */ 31758d7027bSFrank Praznik 0x09, 0x50, /* Usage (50h), */ 31858d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 31958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32058d7027bSFrank Praznik 0x85, 0xAD, /* Report ID (173), */ 32158d7027bSFrank Praznik 0x09, 0x51, /* Usage (51h), */ 32258d7027bSFrank Praznik 0x95, 0x0B, /* Report Count (11), */ 32358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32458d7027bSFrank Praznik 0x85, 0xAE, /* Report ID (174), */ 32558d7027bSFrank Praznik 0x09, 0x52, /* Usage (52h), */ 32658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 32758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32858d7027bSFrank Praznik 0x85, 0xAF, /* Report ID (175), */ 32958d7027bSFrank Praznik 0x09, 0x53, /* Usage (53h), */ 33058d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 33158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33258d7027bSFrank Praznik 0x85, 0xB0, /* Report ID (176), */ 33358d7027bSFrank Praznik 0x09, 0x54, /* Usage (54h), */ 33458d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 33558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33658d7027bSFrank Praznik 0xC0 /* End Collection */ 337ed19d8cfSFrank Praznik }; 338ed19d8cfSFrank Praznik 339d829674dSFrank Praznik /* The default behavior of the Dualshock 4 is to send reports using report 340d829674dSFrank Praznik * type 1 when running over Bluetooth. However, as soon as it receives a 341d829674dSFrank Praznik * report of type 17 to set the LEDs or rumble it starts returning it's state 342d829674dSFrank Praznik * in report 17 instead of 1. Since report 17 is undefined in the default HID 343d829674dSFrank Praznik * descriptor the button and axis definitions must be moved to report 17 or 344d829674dSFrank Praznik * the HID layer won't process the received input once a report is sent. 345d829674dSFrank Praznik */ 346d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = { 347d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 348d829674dSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 349d829674dSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 350d829674dSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 351d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 352d829674dSFrank Praznik 0x95, 0x0A, /* Report Count (9), */ 353d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 354d829674dSFrank Praznik 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ 355d829674dSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 356d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 357d829674dSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 358d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 359d829674dSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 360d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 361d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 362d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 363d829674dSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 364d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 365d829674dSFrank Praznik 0x95, 0x28, /* Report Count (40), */ 366d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 367d829674dSFrank Praznik 0x85, 0x06, /* Report ID (6), */ 368d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 369d829674dSFrank Praznik 0x95, 0x34, /* Report Count (52), */ 370d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 371d829674dSFrank Praznik 0x85, 0x07, /* Report ID (7), */ 372d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 373d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 374d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 375d829674dSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 376d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 377d829674dSFrank Praznik 0x95, 0x2F, /* Report Count (47), */ 378d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 379d829674dSFrank Praznik 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ 380d829674dSFrank Praznik 0x85, 0x03, /* Report ID (3), */ 381d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 382d829674dSFrank Praznik 0x95, 0x26, /* Report Count (38), */ 383d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 384d829674dSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 385d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 386d829674dSFrank Praznik 0x95, 0x2E, /* Report Count (46), */ 387d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 388d829674dSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 389d829674dSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 390d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 391d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 392d829674dSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 393d829674dSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 394d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 395d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 396d829674dSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 397d829674dSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 398d829674dSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 399d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 400d829674dSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 401d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 402d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 403d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 404d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 405d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 406d829674dSFrank Praznik 0x09, 0x30, /* Usage (X), */ 407d829674dSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 408d829674dSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 409d829674dSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 410d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 411d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 412d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 413d829674dSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 414d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 415d829674dSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 416d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 417d829674dSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 418d829674dSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 419d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 420d829674dSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 421d829674dSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 422d829674dSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 423d829674dSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 424d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 425d829674dSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 426d829674dSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 427d829674dSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 428d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 429d829674dSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 430d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 431d829674dSFrank Praznik 0x81, 0x01, /* Input (Constant), */ 432d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 433d829674dSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 434d829674dSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 435d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 436d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 437d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 438d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 439d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 440d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 441d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 442d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 443d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 444d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 445d829674dSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 446d829674dSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 447d829674dSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 448d829674dSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 449d829674dSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 450d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 451d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 452d829674dSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 453d829674dSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 454d829674dSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 455d829674dSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 456d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 457d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 458d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 459d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 460d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 461d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 462d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 463d829674dSFrank Praznik 0x95, 0x31, /* Report Count (51), */ 464d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 465d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 466d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 467d829674dSFrank Praznik 0x95, 0x4D, /* Report Count (77), */ 468d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 469d829674dSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 470d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 471d829674dSFrank Praznik 0x95, 0x8D, /* Report Count (141), */ 472d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 473d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 474d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 475d829674dSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 476d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 477d829674dSFrank Praznik 0x95, 0xCD, /* Report Count (205), */ 478d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 479d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 480d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 481d829674dSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 482d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 483d829674dSFrank Praznik 0x96, 0x0D, 0x01, /* Report Count (269), */ 484d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 485d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 486d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 487d829674dSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 488d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 489d829674dSFrank Praznik 0x96, 0x4D, 0x01, /* Report Count (333), */ 490d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 491d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 492d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 493d829674dSFrank Praznik 0x85, 0x16, /* Report ID (22), */ 494d829674dSFrank Praznik 0x09, 0x2A, /* Usage (2Ah), */ 495d829674dSFrank Praznik 0x96, 0x8D, 0x01, /* Report Count (397), */ 496d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 497d829674dSFrank Praznik 0x09, 0x2B, /* Usage (2Bh), */ 498d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 499d829674dSFrank Praznik 0x85, 0x17, /* Report ID (23), */ 500d829674dSFrank Praznik 0x09, 0x2C, /* Usage (2Ch), */ 501d829674dSFrank Praznik 0x96, 0xCD, 0x01, /* Report Count (461), */ 502d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 503d829674dSFrank Praznik 0x09, 0x2D, /* Usage (2Dh), */ 504d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 505d829674dSFrank Praznik 0x85, 0x18, /* Report ID (24), */ 506d829674dSFrank Praznik 0x09, 0x2E, /* Usage (2Eh), */ 507d829674dSFrank Praznik 0x96, 0x0D, 0x02, /* Report Count (525), */ 508d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 509d829674dSFrank Praznik 0x09, 0x2F, /* Usage (2Fh), */ 510d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 511d829674dSFrank Praznik 0x85, 0x19, /* Report ID (25), */ 512d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 513d829674dSFrank Praznik 0x96, 0x22, 0x02, /* Report Count (546), */ 514d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 515d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 516d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 517d829674dSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 518d829674dSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 519d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 520d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 521d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 522d829674dSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 523d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 524d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 525d829674dSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 526d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 527d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 528d829674dSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 529d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 530d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 531d829674dSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 532d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 533d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 534d829674dSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 535d829674dSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 536d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 537d829674dSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 538d829674dSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 539d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 540d829674dSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 541d829674dSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 542d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 543d829674dSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 544d829674dSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 545d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 546d829674dSFrank Praznik 0xC0 /* End Collection */ 547d829674dSFrank Praznik }; 548d829674dSFrank Praznik 549078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 550078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 551078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 552078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 553078328daSJiri Kosina 554078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 555078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 556078328daSJiri Kosina 557078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 558078328daSJiri Kosina * number but it's not needed for correct operation */ 559078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 560078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 561078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 562078328daSJiri Kosina 563078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 564078328daSJiri Kosina * buttons multiple keypresses are allowed */ 565078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 566078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 567078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 568078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 569078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 570078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 571078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 572078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 573078328daSJiri Kosina 574078328daSJiri Kosina 0xC0, /* MEndCollection */ 575078328daSJiri Kosina 576078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 577078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 578078328daSJiri Kosina 579078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 580078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 581078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 582078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 583078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 584078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 585078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 586078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 587078328daSJiri Kosina 0x80, /* MInput */ 588078328daSJiri Kosina 589078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 590078328daSJiri Kosina * 0xff and 11th is for press indication */ 591078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 592078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 593078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 594078328daSJiri Kosina 595078328daSJiri Kosina /* 12th byte is for battery strength */ 596078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 597078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 598078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 599078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 600078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 601078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 602078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 603078328daSJiri Kosina 604078328daSJiri Kosina 0xC0, /* MEndCollection */ 605078328daSJiri Kosina 606078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 607078328daSJiri Kosina }; 608078328daSJiri Kosina 609078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 610078328daSJiri Kosina [0x01] = KEY_SELECT, 611078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 612078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 613078328daSJiri Kosina [0x04] = BTN_START, 614078328daSJiri Kosina [0x05] = KEY_UP, 615078328daSJiri Kosina [0x06] = KEY_RIGHT, 616078328daSJiri Kosina [0x07] = KEY_DOWN, 617078328daSJiri Kosina [0x08] = KEY_LEFT, 618078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 619078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 620078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 621078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 622078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 623078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 624078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 625078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 626078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 627078328daSJiri Kosina [0x14] = KEY_ENTER, 628078328daSJiri Kosina }; 629078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 630078328daSJiri Kosina [0x00] = KEY_1, 631078328daSJiri Kosina [0x01] = KEY_2, 632078328daSJiri Kosina [0x02] = KEY_3, 633078328daSJiri Kosina [0x03] = KEY_4, 634078328daSJiri Kosina [0x04] = KEY_5, 635078328daSJiri Kosina [0x05] = KEY_6, 636078328daSJiri Kosina [0x06] = KEY_7, 637078328daSJiri Kosina [0x07] = KEY_8, 638078328daSJiri Kosina [0x08] = KEY_9, 639078328daSJiri Kosina [0x09] = KEY_0, 640078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 641078328daSJiri Kosina [0x0f] = KEY_CLEAR, 642078328daSJiri Kosina [0x16] = KEY_EJECTCD, 643078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 644078328daSJiri Kosina [0x28] = KEY_TIME, 645078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 646078328daSJiri Kosina [0x31] = KEY_NEXT, 647078328daSJiri Kosina [0x32] = KEY_PLAY, 648078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 649078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 650078328daSJiri Kosina [0x38] = KEY_STOP, 651078328daSJiri Kosina [0x39] = KEY_PAUSE, 652078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 653078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 654078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 655078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 656078328daSJiri Kosina [0x64] = KEY_AUDIO, 657078328daSJiri Kosina [0x65] = KEY_ANGLE, 658078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 659078328daSJiri Kosina [0x80] = KEY_BLUE, 660078328daSJiri Kosina [0x81] = KEY_RED, 661078328daSJiri Kosina [0x82] = KEY_GREEN, 662078328daSJiri Kosina [0x83] = KEY_YELLOW, 663078328daSJiri Kosina }; 664078328daSJiri Kosina 665f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 666f04d5140SColin Leitner /* The controller has 4 remote buzzers, each with one LED and 5 667f04d5140SColin Leitner * buttons. 668f04d5140SColin Leitner * 669f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 670f04d5140SColin Leitner * 671f04d5140SColin Leitner * Key Offset 672f04d5140SColin Leitner * ------------------- 673f04d5140SColin Leitner * Buzz 1 674f04d5140SColin Leitner * Blue 5 675f04d5140SColin Leitner * Orange 4 676f04d5140SColin Leitner * Green 3 677f04d5140SColin Leitner * Yellow 2 678f04d5140SColin Leitner * 679f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 680f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 681f04d5140SColin Leitner */ 682f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 683f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 684f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 685f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 686f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 687f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 688f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 689f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 690f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 691f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 692f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 693f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 694f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 695f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 696f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 697f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 698f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 699f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 700f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 701f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 702f04d5140SColin Leitner }; 703f04d5140SColin Leitner 704d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = { 705d902f472SFrank Praznik POWER_SUPPLY_PROP_PRESENT, 706d902f472SFrank Praznik POWER_SUPPLY_PROP_CAPACITY, 707d902f472SFrank Praznik POWER_SUPPLY_PROP_SCOPE, 708d902f472SFrank Praznik POWER_SUPPLY_PROP_STATUS, 709d902f472SFrank Praznik }; 710d902f472SFrank Praznik 711cc6e0bbbSJiri Kosina struct sony_sc { 712d902f472SFrank Praznik spinlock_t lock; 7130a286ef2SSven Eckelmann struct hid_device *hdev; 71460781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 715cc6e0bbbSJiri Kosina unsigned long quirks; 7160a286ef2SSven Eckelmann struct work_struct state_worker; 717d902f472SFrank Praznik struct power_supply battery; 718f04d5140SColin Leitner 7199f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 7209f323b68SSven Eckelmann __u8 left; 7219f323b68SSven Eckelmann __u8 right; 7229f323b68SSven Eckelmann #endif 7239f323b68SSven Eckelmann 724d902f472SFrank Praznik __u8 cable_state; 725d902f472SFrank Praznik __u8 battery_charging; 726d902f472SFrank Praznik __u8 battery_capacity; 72760781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 72860781cf4SFrank Praznik __u8 led_count; 729cc6e0bbbSJiri Kosina }; 730cc6e0bbbSJiri Kosina 731078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 732078328daSJiri Kosina unsigned int *rsize) 733078328daSJiri Kosina { 734078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 735078328daSJiri Kosina return ps3remote_rdesc; 736078328daSJiri Kosina } 737078328daSJiri Kosina 738078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 739078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 740078328daSJiri Kosina unsigned long **bit, int *max) 741078328daSJiri Kosina { 742078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 743078328daSJiri Kosina 744078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 745078328daSJiri Kosina return -1; 746078328daSJiri Kosina 747078328daSJiri Kosina switch (usage->collection_index) { 748078328daSJiri Kosina case 1: 749078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 750078328daSJiri Kosina return -1; 751078328daSJiri Kosina 752078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 753078328daSJiri Kosina if (!key) 754078328daSJiri Kosina return -1; 755078328daSJiri Kosina break; 756078328daSJiri Kosina case 2: 757078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 758078328daSJiri Kosina return -1; 759078328daSJiri Kosina 760078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 761078328daSJiri Kosina if (!key) 762078328daSJiri Kosina return -1; 763078328daSJiri Kosina break; 764078328daSJiri Kosina default: 765078328daSJiri Kosina return -1; 766078328daSJiri Kosina } 767078328daSJiri Kosina 768078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 769078328daSJiri Kosina return 1; 770078328daSJiri Kosina } 771078328daSJiri Kosina 772078328daSJiri Kosina 773cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 77473e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 77573e4008dSNikolai Kondrashov unsigned int *rsize) 776cc6e0bbbSJiri Kosina { 777cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 778cc6e0bbbSJiri Kosina 77999d24902SFernando Luis Vázquez Cao /* 78099d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 78199d24902SFernando Luis Vázquez Cao * a constant non-data variable. 78299d24902SFernando Luis Vázquez Cao */ 78399d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 78499d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 78599d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 78699d24902SFernando Luis Vázquez Cao /* usage: mouse */ 78799d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 78899d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 78999d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 790a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 79199d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 792cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 793cc6e0bbbSJiri Kosina } 79461ab44beSSimon Wood 795ed19d8cfSFrank Praznik /* 796ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 797ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 798ed19d8cfSFrank Praznik * modified one. 799ed19d8cfSFrank Praznik */ 800ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 801ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 802ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 803ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 804d829674dSFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { 805d829674dSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); 806d829674dSFrank Praznik rdesc = dualshock4_bt_rdesc; 807d829674dSFrank Praznik *rsize = sizeof(dualshock4_bt_rdesc); 808ed19d8cfSFrank Praznik } 809ed19d8cfSFrank Praznik 81061ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 81161ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 81261ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 81361ab44beSSimon Wood rdesc[83] == 0x75) { 81461ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 81561ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 81661ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 817e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 818e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 819e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 820e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 821e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 822e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 82361ab44beSSimon Wood } 824078328daSJiri Kosina 825078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 826078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 827078328daSJiri Kosina 82873e4008dSNikolai Kondrashov return rdesc; 829cc6e0bbbSJiri Kosina } 830cc6e0bbbSJiri Kosina 831d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) 832d902f472SFrank Praznik { 833d902f472SFrank Praznik static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 834d902f472SFrank Praznik unsigned long flags; 835d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 836d902f472SFrank Praznik 837d902f472SFrank Praznik /* The sixaxis is charging if the battery value is 0xee 838d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 839d902f472SFrank Praznik * It does not report the actual level while charging so it 840d902f472SFrank Praznik * is set to 100% while charging is in progress. 841d902f472SFrank Praznik */ 842d902f472SFrank Praznik if (rd[30] >= 0xee) { 843d902f472SFrank Praznik battery_capacity = 100; 844d902f472SFrank Praznik battery_charging = rd[30] & 0x01; 845d902f472SFrank Praznik } else { 846d902f472SFrank Praznik battery_capacity = sixaxis_battery_capacity[rd[30]]; 847d902f472SFrank Praznik battery_charging = 0; 848d902f472SFrank Praznik } 849d902f472SFrank Praznik cable_state = (rd[31] >> 4) & 0x01; 850d902f472SFrank Praznik 851d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 852d902f472SFrank Praznik sc->cable_state = cable_state; 853d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 854d902f472SFrank Praznik sc->battery_charging = battery_charging; 855d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 856d902f472SFrank Praznik } 857d902f472SFrank Praznik 858d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) 859d902f472SFrank Praznik { 860e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 861e5606230SFrank Praznik struct hid_input, list); 862e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 863d902f472SFrank Praznik unsigned long flags; 864e5606230SFrank Praznik int n, offset = 35; 865d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 866d902f472SFrank Praznik 867d902f472SFrank Praznik /* The lower 4 bits of byte 30 contain the battery level 868d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 869d902f472SFrank Praznik */ 870d902f472SFrank Praznik cable_state = (rd[30] >> 4) & 0x01; 871d902f472SFrank Praznik battery_capacity = rd[30] & 0x0F; 872d902f472SFrank Praznik 873d902f472SFrank Praznik /* On USB the Dualshock 4 battery level goes from 0 to 11. 874d902f472SFrank Praznik * A battery level of 11 means fully charged. 875d902f472SFrank Praznik */ 876d902f472SFrank Praznik if (cable_state && battery_capacity == 11) 877d902f472SFrank Praznik battery_charging = 0; 878d902f472SFrank Praznik else 879d902f472SFrank Praznik battery_charging = 1; 880d902f472SFrank Praznik 881d902f472SFrank Praznik if (battery_capacity > 10) 882d902f472SFrank Praznik battery_capacity--; 883d902f472SFrank Praznik battery_capacity *= 10; 884d902f472SFrank Praznik 885d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 886d902f472SFrank Praznik sc->cable_state = cable_state; 887d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 888d902f472SFrank Praznik sc->battery_charging = battery_charging; 889d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 890e5606230SFrank Praznik 891e5606230SFrank Praznik /* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB. 892e5606230SFrank Praznik * The first 7 bits of the first byte is a counter and bit 8 is a touch 893e5606230SFrank Praznik * indicator that is 0 when pressed and 1 when not pressed. 894e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 895e5606230SFrank Praznik * The data for the second touch is in the same format and immediatly 896e5606230SFrank Praznik * follows the data for the first. 897e5606230SFrank Praznik */ 898e5606230SFrank Praznik for (n = 0; n < 2; n++) { 899e5606230SFrank Praznik __u16 x, y; 900e5606230SFrank Praznik 901e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 902e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 903e5606230SFrank Praznik 904e5606230SFrank Praznik input_mt_slot(input_dev, n); 905e5606230SFrank Praznik input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 906e5606230SFrank Praznik !(rd[offset] >> 7)); 907e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_X, x); 908e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 909e5606230SFrank Praznik 910e5606230SFrank Praznik offset += 4; 911e5606230SFrank Praznik } 912d902f472SFrank Praznik } 913d902f472SFrank Praznik 914c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 915c9e4d877SSimon Wood __u8 *rd, int size) 916c9e4d877SSimon Wood { 917c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 918c9e4d877SSimon Wood 919c9e4d877SSimon Wood /* Sixaxis HID report has acclerometers/gyro with MSByte first, this 920c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 921c9e4d877SSimon Wood */ 922c9e4d877SSimon Wood if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) && 923c9e4d877SSimon Wood rd[0] == 0x01 && size == 49) { 924c9e4d877SSimon Wood swap(rd[41], rd[42]); 925c9e4d877SSimon Wood swap(rd[43], rd[44]); 926c9e4d877SSimon Wood swap(rd[45], rd[46]); 927c9e4d877SSimon Wood swap(rd[47], rd[48]); 928d902f472SFrank Praznik 929d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 930d902f472SFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 931d902f472SFrank Praznik size == 64) { 932d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 933c9e4d877SSimon Wood } 934c9e4d877SSimon Wood 935c9e4d877SSimon Wood return 0; 936c9e4d877SSimon Wood } 937c9e4d877SSimon Wood 938f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 939f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 940f04d5140SColin Leitner unsigned long **bit, int *max) 941f04d5140SColin Leitner { 942f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 943f04d5140SColin Leitner 944f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 945f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 946f04d5140SColin Leitner 947f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 948f04d5140SColin Leitner return -1; 949f04d5140SColin Leitner 950f04d5140SColin Leitner switch (usage->collection_index) { 951f04d5140SColin Leitner case 1: 952f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 953f04d5140SColin Leitner return -1; 954f04d5140SColin Leitner 955f04d5140SColin Leitner key = buzz_keymap[key]; 956f04d5140SColin Leitner if (!key) 957f04d5140SColin Leitner return -1; 958f04d5140SColin Leitner break; 959f04d5140SColin Leitner default: 960f04d5140SColin Leitner return -1; 961f04d5140SColin Leitner } 962f04d5140SColin Leitner 963f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 964f04d5140SColin Leitner return 1; 965f04d5140SColin Leitner } 966f04d5140SColin Leitner 967078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 968078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 969078328daSJiri Kosina 9706f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 9716f498018SBenjamin Tissoires return 0; 972f04d5140SColin Leitner } 973f04d5140SColin Leitner 9745710fabfSAntonio Ospite /* 9755710fabfSAntonio Ospite * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 9765710fabfSAntonio Ospite * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 9775710fabfSAntonio Ospite * so we need to override that forcing HID Output Reports on the Control EP. 9785710fabfSAntonio Ospite * 9795710fabfSAntonio Ospite * There is also another issue about HID Output Reports via USB, the Sixaxis 9805710fabfSAntonio Ospite * does not want the report_id as part of the data packet, so we have to 9815710fabfSAntonio Ospite * discard buf[0] when sending the actual control message, even for numbered 9825710fabfSAntonio Ospite * reports, humpf! 9835710fabfSAntonio Ospite */ 984569b10a5SAntonio Ospite static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 985569b10a5SAntonio Ospite size_t count, unsigned char report_type) 986569b10a5SAntonio Ospite { 987569b10a5SAntonio Ospite struct usb_interface *intf = to_usb_interface(hid->dev.parent); 988569b10a5SAntonio Ospite struct usb_device *dev = interface_to_usbdev(intf); 989569b10a5SAntonio Ospite struct usb_host_interface *interface = intf->cur_altsetting; 990569b10a5SAntonio Ospite int report_id = buf[0]; 991569b10a5SAntonio Ospite int ret; 992569b10a5SAntonio Ospite 9935710fabfSAntonio Ospite if (report_type == HID_OUTPUT_REPORT) { 9945710fabfSAntonio Ospite /* Don't send the Report ID */ 9955710fabfSAntonio Ospite buf++; 9965710fabfSAntonio Ospite count--; 9975710fabfSAntonio Ospite } 9985710fabfSAntonio Ospite 999569b10a5SAntonio Ospite ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1000569b10a5SAntonio Ospite HID_REQ_SET_REPORT, 1001569b10a5SAntonio Ospite USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 1002569b10a5SAntonio Ospite ((report_type + 1) << 8) | report_id, 1003569b10a5SAntonio Ospite interface->desc.bInterfaceNumber, buf, count, 1004569b10a5SAntonio Ospite USB_CTRL_SET_TIMEOUT); 1005569b10a5SAntonio Ospite 10065710fabfSAntonio Ospite /* Count also the Report ID, in case of an Output report. */ 10075710fabfSAntonio Ospite if (ret > 0 && report_type == HID_OUTPUT_REPORT) 10085710fabfSAntonio Ospite ret++; 10095710fabfSAntonio Ospite 1010569b10a5SAntonio Ospite return ret; 1011569b10a5SAntonio Ospite } 1012569b10a5SAntonio Ospite 1013bd28ce00SJiri Slaby /* 1014bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1015bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1016bd28ce00SJiri Slaby * events. 1017bd28ce00SJiri Slaby */ 1018816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1019bd28ce00SJiri Slaby { 1020bd28ce00SJiri Slaby int ret; 1021bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 1022bd28ce00SJiri Slaby 1023bd28ce00SJiri Slaby if (!buf) 1024bd28ce00SJiri Slaby return -ENOMEM; 1025bd28ce00SJiri Slaby 1026cafebc05SBenjamin Tissoires ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1027cafebc05SBenjamin Tissoires HID_REQ_GET_REPORT); 1028f204828aSBenjamin Tissoires 1029bd28ce00SJiri Slaby if (ret < 0) 10304291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 1031bd28ce00SJiri Slaby 1032bd28ce00SJiri Slaby kfree(buf); 1033bd28ce00SJiri Slaby 1034bd28ce00SJiri Slaby return ret; 1035bd28ce00SJiri Slaby } 1036bd28ce00SJiri Slaby 1037816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1038f9ce7c28SBastien Nocera { 1039fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 10407e845d46SBenjamin Tissoires return hid_output_raw_report(hdev, buf, sizeof(buf), 10417e845d46SBenjamin Tissoires HID_FEATURE_REPORT); 1042f9ce7c28SBastien Nocera } 1043f9ce7c28SBastien Nocera 104460781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 1045f04d5140SColin Leitner { 1046f04d5140SColin Leitner struct list_head *report_list = 1047f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1048f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1049f04d5140SColin Leitner struct hid_report, list); 1050f04d5140SColin Leitner __s32 *value = report->field[0]->value; 1051f04d5140SColin Leitner 1052f04d5140SColin Leitner value[0] = 0x00; 105360781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 105460781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 105560781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 105660781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 1057f04d5140SColin Leitner value[5] = 0x00; 1058f04d5140SColin Leitner value[6] = 0x00; 1059f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1060f04d5140SColin Leitner } 1061f04d5140SColin Leitner 106260781cf4SFrank Praznik static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) 10630a286ef2SSven Eckelmann { 10640a286ef2SSven Eckelmann struct sony_sc *drv_data = hid_get_drvdata(hdev); 106560781cf4SFrank Praznik int n; 10660a286ef2SSven Eckelmann 106760781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 106860781cf4SFrank Praznik 106960781cf4SFrank Praznik if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { 10700a286ef2SSven Eckelmann buzz_set_leds(hdev, leds); 107160781cf4SFrank Praznik } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) || 10728ab1676bSFrank Praznik (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) { 107360781cf4SFrank Praznik for (n = 0; n < count; n++) 107460781cf4SFrank Praznik drv_data->led_state[n] = leds[n]; 10750a286ef2SSven Eckelmann schedule_work(&drv_data->state_worker); 10760a286ef2SSven Eckelmann } 10770a286ef2SSven Eckelmann } 10780a286ef2SSven Eckelmann 1079c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1080f04d5140SColin Leitner enum led_brightness value) 1081f04d5140SColin Leitner { 1082f04d5140SColin Leitner struct device *dev = led->dev->parent; 1083f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1084f04d5140SColin Leitner struct sony_sc *drv_data; 1085f04d5140SColin Leitner 1086f04d5140SColin Leitner int n; 1087f04d5140SColin Leitner 1088f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 10892251b85fSSven Eckelmann if (!drv_data) { 1090f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1091f04d5140SColin Leitner return; 1092f04d5140SColin Leitner } 1093f04d5140SColin Leitner 109460781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 10952251b85fSSven Eckelmann if (led == drv_data->leds[n]) { 109660781cf4SFrank Praznik if (value != drv_data->led_state[n]) { 109760781cf4SFrank Praznik drv_data->led_state[n] = value; 109860781cf4SFrank Praznik sony_set_leds(hdev, drv_data->led_state, drv_data->led_count); 1099f04d5140SColin Leitner } 1100f04d5140SColin Leitner break; 1101f04d5140SColin Leitner } 1102f04d5140SColin Leitner } 1103f04d5140SColin Leitner } 1104f04d5140SColin Leitner 1105c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1106f04d5140SColin Leitner { 1107f04d5140SColin Leitner struct device *dev = led->dev->parent; 1108f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1109f04d5140SColin Leitner struct sony_sc *drv_data; 1110f04d5140SColin Leitner 1111f04d5140SColin Leitner int n; 1112f04d5140SColin Leitner 1113f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 11142251b85fSSven Eckelmann if (!drv_data) { 1115f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1116f04d5140SColin Leitner return LED_OFF; 1117f04d5140SColin Leitner } 1118f04d5140SColin Leitner 111960781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 11207db7504aSSimon Wood if (led == drv_data->leds[n]) 11217db7504aSSimon Wood return drv_data->led_state[n]; 1122f04d5140SColin Leitner } 1123f04d5140SColin Leitner 11247db7504aSSimon Wood return LED_OFF; 1125f04d5140SColin Leitner } 1126f04d5140SColin Leitner 11270a286ef2SSven Eckelmann static void sony_leds_remove(struct hid_device *hdev) 11280a286ef2SSven Eckelmann { 11290a286ef2SSven Eckelmann struct sony_sc *drv_data; 11300a286ef2SSven Eckelmann struct led_classdev *led; 11310a286ef2SSven Eckelmann int n; 11320a286ef2SSven Eckelmann 11330a286ef2SSven Eckelmann drv_data = hid_get_drvdata(hdev); 11340a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 11350a286ef2SSven Eckelmann 113660781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 11370a286ef2SSven Eckelmann led = drv_data->leds[n]; 11380a286ef2SSven Eckelmann drv_data->leds[n] = NULL; 11390a286ef2SSven Eckelmann if (!led) 11400a286ef2SSven Eckelmann continue; 11410a286ef2SSven Eckelmann led_classdev_unregister(led); 11420a286ef2SSven Eckelmann kfree(led); 11430a286ef2SSven Eckelmann } 114460781cf4SFrank Praznik 114560781cf4SFrank Praznik drv_data->led_count = 0; 11460a286ef2SSven Eckelmann } 11470a286ef2SSven Eckelmann 1148c5382519SSven Eckelmann static int sony_leds_init(struct hid_device *hdev) 1149f04d5140SColin Leitner { 1150f04d5140SColin Leitner struct sony_sc *drv_data; 115140e32ee6SJiri Kosina int n, ret = 0; 115260781cf4SFrank Praznik int max_brightness; 115361ebca93SFrank Praznik int use_colors; 115440e32ee6SJiri Kosina struct led_classdev *led; 115540e32ee6SJiri Kosina size_t name_sz; 115640e32ee6SJiri Kosina char *name; 11570a286ef2SSven Eckelmann size_t name_len; 11580a286ef2SSven Eckelmann const char *name_fmt; 115961ebca93SFrank Praznik static const char * const color_str[] = { "red", "green", "blue" }; 116060781cf4SFrank Praznik static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 }; 1161f04d5140SColin Leitner 1162f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 11630a286ef2SSven Eckelmann BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT)); 1164f04d5140SColin Leitner 11650a286ef2SSven Eckelmann if (drv_data->quirks & BUZZ_CONTROLLER) { 116661ebca93SFrank Praznik drv_data->led_count = 4; 116761ebca93SFrank Praznik max_brightness = 1; 116861ebca93SFrank Praznik use_colors = 0; 11690a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 11700a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 11719446edb9SKees Cook /* Validate expected report characteristics. */ 11729446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 11739446edb9SKees Cook return -ENODEV; 117461ebca93SFrank Praznik } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) { 117560781cf4SFrank Praznik drv_data->led_count = 3; 117660781cf4SFrank Praznik max_brightness = 255; 117761ebca93SFrank Praznik use_colors = 1; 117861ebca93SFrank Praznik name_len = 0; 117961ebca93SFrank Praznik name_fmt = "%s:%s"; 118060781cf4SFrank Praznik } else { 118160781cf4SFrank Praznik drv_data->led_count = 4; 118260781cf4SFrank Praznik max_brightness = 1; 118361ebca93SFrank Praznik use_colors = 0; 118461ebca93SFrank Praznik name_len = strlen("::sony#"); 118561ebca93SFrank Praznik name_fmt = "%s::sony%d"; 118660781cf4SFrank Praznik } 118760781cf4SFrank Praznik 1188f04d5140SColin Leitner /* Clear LEDs as we have no way of reading their initial state. This is 1189f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1190f04d5140SColin Leitner * LEDs to on */ 119160781cf4SFrank Praznik sony_set_leds(hdev, initial_values, drv_data->led_count); 1192f04d5140SColin Leitner 11930a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1194f04d5140SColin Leitner 119560781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 119661ebca93SFrank Praznik 119761ebca93SFrank Praznik if (use_colors) 119861ebca93SFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2; 119961ebca93SFrank Praznik 1200f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1201f04d5140SColin Leitner if (!led) { 1202f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 12038cd5fcdaSJulia Lawall ret = -ENOMEM; 1204f04d5140SColin Leitner goto error_leds; 1205f04d5140SColin Leitner } 1206f04d5140SColin Leitner 1207f04d5140SColin Leitner name = (void *)(&led[1]); 120861ebca93SFrank Praznik if (use_colors) 120961ebca93SFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_str[n]); 121061ebca93SFrank Praznik else 12110a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1212f04d5140SColin Leitner led->name = name; 1213f04d5140SColin Leitner led->brightness = 0; 121460781cf4SFrank Praznik led->max_brightness = max_brightness; 1215c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1216c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1217f04d5140SColin Leitner 12188cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 12198cd5fcdaSJulia Lawall if (ret) { 1220f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 1221f04d5140SColin Leitner kfree(led); 1222f04d5140SColin Leitner goto error_leds; 1223f04d5140SColin Leitner } 1224f04d5140SColin Leitner 12252251b85fSSven Eckelmann drv_data->leds[n] = led; 1226f04d5140SColin Leitner } 1227f04d5140SColin Leitner 1228f04d5140SColin Leitner return ret; 1229f04d5140SColin Leitner 1230f04d5140SColin Leitner error_leds: 12310a286ef2SSven Eckelmann sony_leds_remove(hdev); 1232f04d5140SColin Leitner 1233f04d5140SColin Leitner return ret; 1234f04d5140SColin Leitner } 1235f04d5140SColin Leitner 1236cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 1237a08c22c0SSven Eckelmann { 123892b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1239a08c22c0SSven Eckelmann unsigned char buf[] = { 1240a08c22c0SSven Eckelmann 0x01, 1241a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 12420a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1243a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1244a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1245a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1246a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1247a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 1248a08c22c0SSven Eckelmann }; 12499f323b68SSven Eckelmann 12500a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 12510bd88dd3SFrank Praznik buf[3] = sc->right ? 1 : 0; 12529f323b68SSven Eckelmann buf[5] = sc->left; 12530a286ef2SSven Eckelmann #endif 12540a286ef2SSven Eckelmann 125560781cf4SFrank Praznik buf[10] |= sc->led_state[0] << 1; 125660781cf4SFrank Praznik buf[10] |= sc->led_state[1] << 2; 125760781cf4SFrank Praznik buf[10] |= sc->led_state[2] << 3; 125860781cf4SFrank Praznik buf[10] |= sc->led_state[3] << 4; 12599f323b68SSven Eckelmann 12607e845d46SBenjamin Tissoires hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT); 12619f323b68SSven Eckelmann } 12629f323b68SSven Eckelmann 12630bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 12640bd88dd3SFrank Praznik { 12650bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 12660da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 126748220237SFrank Praznik int offset; 12680da8ea65SFrank Praznik 1269*fdcf105dSFrank Praznik __u8 buf[78] = { 0 }; 127048220237SFrank Praznik 1271*fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 127248220237SFrank Praznik buf[0] = 0x05; 127348220237SFrank Praznik buf[1] = 0x03; 127448220237SFrank Praznik offset = 4; 1275*fdcf105dSFrank Praznik } else { 1276*fdcf105dSFrank Praznik buf[0] = 0x11; 1277*fdcf105dSFrank Praznik buf[1] = 0xB0; 1278*fdcf105dSFrank Praznik buf[3] = 0x0F; 1279*fdcf105dSFrank Praznik offset = 6; 1280*fdcf105dSFrank Praznik } 12810bd88dd3SFrank Praznik 12820bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 128348220237SFrank Praznik buf[offset++] = sc->right; 128448220237SFrank Praznik buf[offset++] = sc->left; 128548220237SFrank Praznik #else 128648220237SFrank Praznik offset += 2; 12870bd88dd3SFrank Praznik #endif 12880bd88dd3SFrank Praznik 128948220237SFrank Praznik buf[offset++] = sc->led_state[0]; 129048220237SFrank Praznik buf[offset++] = sc->led_state[1]; 129148220237SFrank Praznik buf[offset++] = sc->led_state[2]; 129260781cf4SFrank Praznik 1293*fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1294*fdcf105dSFrank Praznik hid_hw_output_report(hdev, buf, 32); 1295*fdcf105dSFrank Praznik else 1296*fdcf105dSFrank Praznik hid_hw_raw_request(hdev, 0x11, buf, 78, 1297*fdcf105dSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 12980bd88dd3SFrank Praznik } 12990bd88dd3SFrank Praznik 13000a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 13019f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 13029f323b68SSven Eckelmann struct ff_effect *effect) 13039f323b68SSven Eckelmann { 1304a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 13059f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 1306a08c22c0SSven Eckelmann 1307a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 1308a08c22c0SSven Eckelmann return 0; 1309a08c22c0SSven Eckelmann 13109f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 13110bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 1312a08c22c0SSven Eckelmann 131392b5c411SSven Eckelmann schedule_work(&sc->state_worker); 13149f323b68SSven Eckelmann return 0; 1315a08c22c0SSven Eckelmann } 1316a08c22c0SSven Eckelmann 1317a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 1318a08c22c0SSven Eckelmann { 1319a08c22c0SSven Eckelmann struct hid_input *hidinput = list_entry(hdev->inputs.next, 1320a08c22c0SSven Eckelmann struct hid_input, list); 1321a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 1322a08c22c0SSven Eckelmann 1323a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 1324a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 1325a08c22c0SSven Eckelmann } 1326a08c22c0SSven Eckelmann 13279f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 13289f323b68SSven Eckelmann { 13299f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hdev); 13309f323b68SSven Eckelmann 133192b5c411SSven Eckelmann cancel_work_sync(&sc->state_worker); 13329f323b68SSven Eckelmann } 13339f323b68SSven Eckelmann 1334a08c22c0SSven Eckelmann #else 1335a08c22c0SSven Eckelmann static int sony_init_ff(struct hid_device *hdev) 1336a08c22c0SSven Eckelmann { 1337a08c22c0SSven Eckelmann return 0; 1338a08c22c0SSven Eckelmann } 13399f323b68SSven Eckelmann 13409f323b68SSven Eckelmann static void sony_destroy_ff(struct hid_device *hdev) 13419f323b68SSven Eckelmann { 13429f323b68SSven Eckelmann } 1343a08c22c0SSven Eckelmann #endif 1344a08c22c0SSven Eckelmann 1345d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 1346d902f472SFrank Praznik enum power_supply_property psp, 1347d902f472SFrank Praznik union power_supply_propval *val) 1348d902f472SFrank Praznik { 1349d902f472SFrank Praznik struct sony_sc *sc = container_of(psy, struct sony_sc, battery); 1350d902f472SFrank Praznik unsigned long flags; 1351d902f472SFrank Praznik int ret = 0; 1352d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 1353d902f472SFrank Praznik 1354d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 1355d902f472SFrank Praznik battery_charging = sc->battery_charging; 1356d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 1357d902f472SFrank Praznik cable_state = sc->cable_state; 1358d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 1359d902f472SFrank Praznik 1360d902f472SFrank Praznik switch (psp) { 1361d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 1362d902f472SFrank Praznik val->intval = 1; 1363d902f472SFrank Praznik break; 1364d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 1365d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 1366d902f472SFrank Praznik break; 1367d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 1368d902f472SFrank Praznik val->intval = battery_capacity; 1369d902f472SFrank Praznik break; 1370d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 1371d902f472SFrank Praznik if (battery_charging) 1372d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 1373d902f472SFrank Praznik else 1374d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 1375d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 1376d902f472SFrank Praznik else 1377d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1378d902f472SFrank Praznik break; 1379d902f472SFrank Praznik default: 1380d902f472SFrank Praznik ret = -EINVAL; 1381d902f472SFrank Praznik break; 1382d902f472SFrank Praznik } 1383d902f472SFrank Praznik return ret; 1384d902f472SFrank Praznik } 1385d902f472SFrank Praznik 1386d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc) 1387d902f472SFrank Praznik { 1388d902f472SFrank Praznik static atomic_t power_id_seq = ATOMIC_INIT(0); 1389d902f472SFrank Praznik unsigned long power_id; 1390d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 1391d902f472SFrank Praznik int ret; 1392d902f472SFrank Praznik 1393d902f472SFrank Praznik power_id = (unsigned long)atomic_inc_return(&power_id_seq); 1394d902f472SFrank Praznik 1395d902f472SFrank Praznik sc->battery.properties = sony_battery_props; 1396d902f472SFrank Praznik sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); 1397d902f472SFrank Praznik sc->battery.get_property = sony_battery_get_property; 1398d902f472SFrank Praznik sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; 1399d902f472SFrank Praznik sc->battery.use_for_apm = 0; 1400d902f472SFrank Praznik sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu", 1401d902f472SFrank Praznik power_id); 1402d902f472SFrank Praznik if (!sc->battery.name) 1403d902f472SFrank Praznik return -ENOMEM; 1404d902f472SFrank Praznik 1405d902f472SFrank Praznik ret = power_supply_register(&hdev->dev, &sc->battery); 1406d902f472SFrank Praznik if (ret) { 1407d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 1408d902f472SFrank Praznik goto err_free; 1409d902f472SFrank Praznik } 1410d902f472SFrank Praznik 1411d902f472SFrank Praznik power_supply_powers(&sc->battery, &hdev->dev); 1412d902f472SFrank Praznik return 0; 1413d902f472SFrank Praznik 1414d902f472SFrank Praznik err_free: 1415d902f472SFrank Praznik kfree(sc->battery.name); 1416d902f472SFrank Praznik sc->battery.name = NULL; 1417d902f472SFrank Praznik return ret; 1418d902f472SFrank Praznik } 1419d902f472SFrank Praznik 1420d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 1421d902f472SFrank Praznik { 1422d902f472SFrank Praznik if (!sc->battery.name) 1423d902f472SFrank Praznik return; 1424d902f472SFrank Praznik 1425d902f472SFrank Praznik power_supply_unregister(&sc->battery); 1426d902f472SFrank Praznik kfree(sc->battery.name); 1427d902f472SFrank Praznik sc->battery.name = NULL; 1428d902f472SFrank Praznik } 1429d902f472SFrank Praznik 1430e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1431e5606230SFrank Praznik int w, int h) 1432e5606230SFrank Praznik { 1433e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1434e5606230SFrank Praznik struct hid_input, list); 1435e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 1436e5606230SFrank Praznik int ret; 1437e5606230SFrank Praznik 1438e5606230SFrank Praznik ret = input_mt_init_slots(input_dev, touch_count, 0); 1439e5606230SFrank Praznik if (ret < 0) { 1440e5606230SFrank Praznik hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); 1441e5606230SFrank Praznik return ret; 1442e5606230SFrank Praznik } 1443e5606230SFrank Praznik 1444e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); 1445e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); 1446e5606230SFrank Praznik 1447e5606230SFrank Praznik return 0; 1448e5606230SFrank Praznik } 1449e5606230SFrank Praznik 1450bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1451bd28ce00SJiri Slaby { 1452bd28ce00SJiri Slaby int ret; 1453cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1454cc6e0bbbSJiri Kosina struct sony_sc *sc; 1455f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1456cc6e0bbbSJiri Kosina 1457abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1458cc6e0bbbSJiri Kosina if (sc == NULL) { 14594291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1460cc6e0bbbSJiri Kosina return -ENOMEM; 1461cc6e0bbbSJiri Kosina } 1462cc6e0bbbSJiri Kosina 1463cc6e0bbbSJiri Kosina sc->quirks = quirks; 1464cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 14650a286ef2SSven Eckelmann sc->hdev = hdev; 1466bd28ce00SJiri Slaby 1467bd28ce00SJiri Slaby ret = hid_parse(hdev); 1468bd28ce00SJiri Slaby if (ret) { 14694291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1470abf832bfSBenjamin Tissoires return ret; 1471bd28ce00SJiri Slaby } 1472bd28ce00SJiri Slaby 1473f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1474f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1475f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 1476f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1477f04d5140SColin Leitner else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 1478f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1479f04d5140SColin Leitner 1480f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1481bd28ce00SJiri Slaby if (ret) { 14824291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1483abf832bfSBenjamin Tissoires return ret; 1484bd28ce00SJiri Slaby } 1485bd28ce00SJiri Slaby 1486569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1487569b10a5SAntonio Ospite hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; 1488816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 1489cad665a2SFrank Praznik INIT_WORK(&sc->state_worker, sixaxis_state_worker); 1490569b10a5SAntonio Ospite } 1491816651a7SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 1492816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 14938ab1676bSFrank Praznik else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1494e5606230SFrank Praznik /* The Dualshock 4 touchpad supports 2 touches and has a 1495e5606230SFrank Praznik * resolution of 1920x940. 1496e5606230SFrank Praznik */ 1497e5606230SFrank Praznik ret = sony_register_touchpad(sc, 2, 1920, 940); 1498e5606230SFrank Praznik if (ret < 0) 1499e5606230SFrank Praznik goto err_stop; 1500e5606230SFrank Praznik 15010bd88dd3SFrank Praznik INIT_WORK(&sc->state_worker, dualshock4_state_worker); 15020bd88dd3SFrank Praznik } else { 15030bd88dd3SFrank Praznik ret = 0; 15040bd88dd3SFrank Praznik } 1505f9ce7c28SBastien Nocera 15064dfdc464SJiri Kosina if (ret < 0) 1507bd28ce00SJiri Slaby goto err_stop; 1508bd28ce00SJiri Slaby 15090a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 15100a286ef2SSven Eckelmann ret = sony_leds_init(hdev); 15110a286ef2SSven Eckelmann if (ret < 0) 15120a286ef2SSven Eckelmann goto err_stop; 15130a286ef2SSven Eckelmann } 15140a286ef2SSven Eckelmann 1515d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1516d902f472SFrank Praznik ret = sony_battery_probe(sc); 1517a08c22c0SSven Eckelmann if (ret < 0) 1518a08c22c0SSven Eckelmann goto err_stop; 1519a08c22c0SSven Eckelmann 1520d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 1521d902f472SFrank Praznik ret = hid_hw_open(hdev); 1522d902f472SFrank Praznik if (ret < 0) { 1523d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 1524d902f472SFrank Praznik goto err_stop; 1525d902f472SFrank Praznik } 1526d902f472SFrank Praznik } 1527d902f472SFrank Praznik 1528d902f472SFrank Praznik ret = sony_init_ff(hdev); 1529d902f472SFrank Praznik if (ret < 0) 1530d902f472SFrank Praznik goto err_close; 1531d902f472SFrank Praznik 1532bd28ce00SJiri Slaby return 0; 1533d902f472SFrank Praznik err_close: 1534d902f472SFrank Praznik hid_hw_close(hdev); 1535bd28ce00SJiri Slaby err_stop: 15360a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 15370a286ef2SSven Eckelmann sony_leds_remove(hdev); 1538d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 1539d902f472SFrank Praznik sony_battery_remove(sc); 1540bd28ce00SJiri Slaby hid_hw_stop(hdev); 1541bd28ce00SJiri Slaby return ret; 1542bd28ce00SJiri Slaby } 1543bd28ce00SJiri Slaby 1544cc6e0bbbSJiri Kosina static void sony_remove(struct hid_device *hdev) 1545cc6e0bbbSJiri Kosina { 1546f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1547f04d5140SColin Leitner 15480a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1549c5382519SSven Eckelmann sony_leds_remove(hdev); 1550f04d5140SColin Leitner 1551d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1552d902f472SFrank Praznik hid_hw_close(hdev); 1553d902f472SFrank Praznik sony_battery_remove(sc); 1554d902f472SFrank Praznik } 1555d902f472SFrank Praznik 15569f323b68SSven Eckelmann sony_destroy_ff(hdev); 15579f323b68SSven Eckelmann 1558cc6e0bbbSJiri Kosina hid_hw_stop(hdev); 1559cc6e0bbbSJiri Kosina } 1560cc6e0bbbSJiri Kosina 1561bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 1562816651a7SAntonio Ospite { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1563816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_USB }, 156435dca5b4SJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 156535dca5b4SJiri Kosina .driver_data = SIXAXIS_CONTROLLER_USB }, 1566816651a7SAntonio Ospite { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1567816651a7SAntonio Ospite .driver_data = SIXAXIS_CONTROLLER_BT }, 1568cc6e0bbbSJiri Kosina { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 1569cc6e0bbbSJiri Kosina .driver_data = VAIO_RDESC_CONSTANT }, 1570a4649184SFernando Luis Vázquez Cao { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 1571a4649184SFernando Luis Vázquez Cao .driver_data = VAIO_RDESC_CONSTANT }, 1572f04d5140SColin Leitner /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 1573f04d5140SColin Leitner * Logitech joystick from the device descriptor. */ 1574f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 1575f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1576f04d5140SColin Leitner { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 1577f04d5140SColin Leitner .driver_data = BUZZ_CONTROLLER }, 1578078328daSJiri Kosina /* PS3 BD Remote Control */ 1579078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 1580078328daSJiri Kosina .driver_data = PS3REMOTE }, 1581078328daSJiri Kosina /* Logitech Harmony Adapter for PS3 */ 1582078328daSJiri Kosina { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 1583078328daSJiri Kosina .driver_data = PS3REMOTE }, 15840bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 15850bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 15868ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 15870bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 15888ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 1589bd28ce00SJiri Slaby { } 1590bd28ce00SJiri Slaby }; 1591bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 1592bd28ce00SJiri Slaby 1593bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 1594bd28ce00SJiri Slaby .name = "sony", 1595bd28ce00SJiri Slaby .id_table = sony_devices, 1596f04d5140SColin Leitner .input_mapping = sony_mapping, 1597bd28ce00SJiri Slaby .probe = sony_probe, 1598cc6e0bbbSJiri Kosina .remove = sony_remove, 1599cc6e0bbbSJiri Kosina .report_fixup = sony_report_fixup, 1600c9e4d877SSimon Wood .raw_event = sony_raw_event 1601bd28ce00SJiri Slaby }; 1602f425458eSH Hartley Sweeten module_hid_driver(sony_driver); 1603bd28ce00SJiri Slaby 1604bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 1605