1bd28ce00SJiri Slaby /* 2078328daSJiri Kosina * HID driver for Sony / PS2 / PS3 BD devices. 3bd28ce00SJiri Slaby * 4bd28ce00SJiri Slaby * Copyright (c) 1999 Andreas Gal 5bd28ce00SJiri Slaby * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6bd28ce00SJiri Slaby * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7bd28ce00SJiri Slaby * Copyright (c) 2008 Jiri Slaby 8078328daSJiri Kosina * Copyright (c) 2012 David Dillow <dave@thedillows.org> 9078328daSJiri Kosina * Copyright (c) 2006-2013 Jiri Kosina 10f04d5140SColin Leitner * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> 11bd28ce00SJiri Slaby */ 12bd28ce00SJiri Slaby 13bd28ce00SJiri Slaby /* 14bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 15bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 16bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 17bd28ce00SJiri Slaby * any later version. 18bd28ce00SJiri Slaby */ 19bd28ce00SJiri Slaby 20ad142b9eSFrank Praznik /* 21ad142b9eSFrank Praznik * NOTE: in order for the Sony PS3 BD Remote Control to be found by 22078328daSJiri Kosina * a Bluetooth host, the key combination Start+Enter has to be kept pressed 23078328daSJiri Kosina * for about 7 seconds with the Bluetooth Host Controller in discovering mode. 24078328daSJiri Kosina * 25078328daSJiri Kosina * There will be no PIN request from the device. 26078328daSJiri Kosina */ 27078328daSJiri Kosina 28bd28ce00SJiri Slaby #include <linux/device.h> 29bd28ce00SJiri Slaby #include <linux/hid.h> 30bd28ce00SJiri Slaby #include <linux/module.h> 315a0e3ad6STejun Heo #include <linux/slab.h> 3240e32ee6SJiri Kosina #include <linux/leds.h> 33d902f472SFrank Praznik #include <linux/power_supply.h> 34d902f472SFrank Praznik #include <linux/spinlock.h> 35d2d782fcSFrank Praznik #include <linux/list.h> 368025087aSFrank Praznik #include <linux/idr.h> 37e5606230SFrank Praznik #include <linux/input/mt.h> 38bd28ce00SJiri Slaby 39bd28ce00SJiri Slaby #include "hid-ids.h" 40bd28ce00SJiri Slaby 41f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 42f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 43f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 44f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 45f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 468ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 478ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 48cc6e0bbbSJiri Kosina 49fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 5068330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ 5168330d83SFrank Praznik DUALSHOCK4_CONTROLLER_BT) 52fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 5368330d83SFrank Praznik DUALSHOCK4_CONTROLLER) 54fee4e2d5SFrank Praznik #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 55c8de9dbbSFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 5660781cf4SFrank Praznik 5760781cf4SFrank Praznik #define MAX_LEDS 4 580a286ef2SSven Eckelmann 5961ab44beSSimon Wood static const u8 sixaxis_rdesc_fixup[] = { 6061ab44beSSimon Wood 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 6161ab44beSSimon Wood 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 6261ab44beSSimon Wood 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 6361ab44beSSimon Wood }; 6461ab44beSSimon Wood 65e57a67daSMauro Carvalho Chehab static const u8 sixaxis_rdesc_fixup2[] = { 66e57a67daSMauro Carvalho Chehab 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 67e57a67daSMauro Carvalho Chehab 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 68e57a67daSMauro Carvalho Chehab 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 69e57a67daSMauro Carvalho Chehab 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 70e57a67daSMauro Carvalho Chehab 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 71e57a67daSMauro Carvalho Chehab 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 72e57a67daSMauro Carvalho Chehab 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 73e57a67daSMauro Carvalho Chehab 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 74e57a67daSMauro Carvalho Chehab 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 75e57a67daSMauro Carvalho Chehab 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 76e57a67daSMauro Carvalho Chehab 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 77e57a67daSMauro Carvalho Chehab 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 78e57a67daSMauro Carvalho Chehab 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 79e57a67daSMauro Carvalho Chehab 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 80e57a67daSMauro Carvalho Chehab 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 81e57a67daSMauro Carvalho Chehab 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 82e57a67daSMauro Carvalho Chehab 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 83e57a67daSMauro Carvalho Chehab 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 84e57a67daSMauro Carvalho Chehab 0xb1, 0x02, 0xc0, 0xc0, 85e57a67daSMauro Carvalho Chehab }; 86e57a67daSMauro Carvalho Chehab 87ad142b9eSFrank Praznik /* 88ad142b9eSFrank Praznik * The default descriptor doesn't provide mapping for the accelerometers 8958d7027bSFrank Praznik * or orientation sensors. This fixed descriptor maps the accelerometers 9058d7027bSFrank Praznik * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors 9158d7027bSFrank Praznik * to usage values 0x43, 0x44 and 0x45. 9258d7027bSFrank Praznik */ 93ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = { 9458d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 9558d7027bSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 9658d7027bSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 9758d7027bSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 9858d7027bSFrank Praznik 0x09, 0x30, /* Usage (X), */ 9958d7027bSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 10058d7027bSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 10158d7027bSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 10258d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 10358d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 10458d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 10558d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 10658d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 10758d7027bSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 10858d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 10958d7027bSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 11058d7027bSFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 11158d7027bSFrank Praznik 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 11258d7027bSFrank Praznik 0x65, 0x14, /* Unit (Degrees), */ 11358d7027bSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 11458d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 11558d7027bSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 11658d7027bSFrank Praznik 0x65, 0x00, /* Unit, */ 11758d7027bSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 11858d7027bSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 11958d7027bSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 12058d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 12158d7027bSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 12258d7027bSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 12358d7027bSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 12458d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 12558d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 12658d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 12758d7027bSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 12858d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 12958d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 13058d7027bSFrank Praznik 0x25, 0x7F, /* Logical Maximum (127), */ 13158d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 13258d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 13358d7027bSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 13458d7027bSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 13558d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 13658d7027bSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 13758d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 13858d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 13958d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 14058d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 14158d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 14258d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 14358d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 14458d7027bSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 14558d7027bSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 14658d7027bSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 14758d7027bSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 14858d7027bSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 14958d7027bSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 15058d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 15158d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15258d7027bSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 15358d7027bSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 15458d7027bSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 15558d7027bSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 15658d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 15758d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 15858d7027bSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 15958d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 16058d7027bSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 16158d7027bSFrank Praznik 0x25, 0xFF, /* Logical Maximum (255), */ 16258d7027bSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 16358d7027bSFrank Praznik 0x95, 0x27, /* Report Count (39), */ 16458d7027bSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 16558d7027bSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 16658d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 16758d7027bSFrank Praznik 0x95, 0x1F, /* Report Count (31), */ 16858d7027bSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 16958d7027bSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 17058d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 17158d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 17258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17358d7027bSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 17458d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 17558d7027bSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 17658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 17758d7027bSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 17858d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 17958d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 18058d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18158d7027bSFrank Praznik 0x85, 0x10, /* Report ID (16), */ 18258d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 18358d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 18458d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18558d7027bSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 18658d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 18758d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 18858d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 18958d7027bSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 19058d7027bSFrank Praznik 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */ 19158d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 19258d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 19358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19458d7027bSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 19558d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 19658d7027bSFrank Praznik 0x95, 0x16, /* Report Count (22), */ 19758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 19858d7027bSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 19958d7027bSFrank Praznik 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */ 20058d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 20158d7027bSFrank Praznik 0x95, 0x10, /* Report Count (16), */ 20258d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20358d7027bSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 20458d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 20558d7027bSFrank Praznik 0x95, 0x2C, /* Report Count (44), */ 20658d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 20758d7027bSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 20858d7027bSFrank Praznik 0x85, 0x80, /* Report ID (128), */ 20958d7027bSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 21058d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 21158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21258d7027bSFrank Praznik 0x85, 0x81, /* Report ID (129), */ 21358d7027bSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 21458d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 21558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 21658d7027bSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 21758d7027bSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 21858d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 21958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22058d7027bSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 22158d7027bSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 22258d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 22358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22458d7027bSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 22558d7027bSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 22658d7027bSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 22758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 22858d7027bSFrank Praznik 0x85, 0x85, /* Report ID (133), */ 22958d7027bSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 23058d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 23158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23258d7027bSFrank Praznik 0x85, 0x86, /* Report ID (134), */ 23358d7027bSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 23458d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 23558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 23658d7027bSFrank Praznik 0x85, 0x87, /* Report ID (135), */ 23758d7027bSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 23858d7027bSFrank Praznik 0x95, 0x23, /* Report Count (35), */ 23958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24058d7027bSFrank Praznik 0x85, 0x88, /* Report ID (136), */ 24158d7027bSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 24258d7027bSFrank Praznik 0x95, 0x22, /* Report Count (34), */ 24358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24458d7027bSFrank Praznik 0x85, 0x89, /* Report ID (137), */ 24558d7027bSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 24658d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 24758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 24858d7027bSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 24958d7027bSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 25058d7027bSFrank Praznik 0x95, 0x05, /* Report Count (5), */ 25158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25258d7027bSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 25358d7027bSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 25458d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 25558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 25658d7027bSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 25758d7027bSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 25858d7027bSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 25958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26058d7027bSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 26158d7027bSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 26258d7027bSFrank Praznik 0x95, 0x0C, /* Report Count (12), */ 26358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26458d7027bSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 26558d7027bSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 26658d7027bSFrank Praznik 0x95, 0x06, /* Report Count (6), */ 26758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 26858d7027bSFrank Praznik 0x85, 0xA1, /* Report ID (161), */ 26958d7027bSFrank Praznik 0x09, 0x41, /* Usage (41h), */ 27058d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 27158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27258d7027bSFrank Praznik 0x85, 0xA2, /* Report ID (162), */ 27358d7027bSFrank Praznik 0x09, 0x42, /* Usage (42h), */ 27458d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 27558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 27658d7027bSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 27758d7027bSFrank Praznik 0x09, 0x43, /* Usage (43h), */ 27858d7027bSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 27958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28058d7027bSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 28158d7027bSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 28258d7027bSFrank Praznik 0x95, 0x0D, /* Report Count (13), */ 28358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28458d7027bSFrank Praznik 0x85, 0xA5, /* Report ID (165), */ 28558d7027bSFrank Praznik 0x09, 0x45, /* Usage (45h), */ 28658d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 28758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 28858d7027bSFrank Praznik 0x85, 0xA6, /* Report ID (166), */ 28958d7027bSFrank Praznik 0x09, 0x46, /* Usage (46h), */ 29058d7027bSFrank Praznik 0x95, 0x15, /* Report Count (21), */ 29158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29258d7027bSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 29358d7027bSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 29458d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 29558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 29658d7027bSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 29758d7027bSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 29858d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 29958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30058d7027bSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 30158d7027bSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 30258d7027bSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 30358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30458d7027bSFrank Praznik 0x85, 0xA7, /* Report ID (167), */ 30558d7027bSFrank Praznik 0x09, 0x4A, /* Usage (4Ah), */ 30658d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 30758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 30858d7027bSFrank Praznik 0x85, 0xA8, /* Report ID (168), */ 30958d7027bSFrank Praznik 0x09, 0x4B, /* Usage (4Bh), */ 31058d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 31158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31258d7027bSFrank Praznik 0x85, 0xA9, /* Report ID (169), */ 31358d7027bSFrank Praznik 0x09, 0x4C, /* Usage (4Ch), */ 31458d7027bSFrank Praznik 0x95, 0x08, /* Report Count (8), */ 31558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 31658d7027bSFrank Praznik 0x85, 0xAA, /* Report ID (170), */ 31758d7027bSFrank Praznik 0x09, 0x4E, /* Usage (4Eh), */ 31858d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 31958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32058d7027bSFrank Praznik 0x85, 0xAB, /* Report ID (171), */ 32158d7027bSFrank Praznik 0x09, 0x4F, /* Usage (4Fh), */ 32258d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 32358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32458d7027bSFrank Praznik 0x85, 0xAC, /* Report ID (172), */ 32558d7027bSFrank Praznik 0x09, 0x50, /* Usage (50h), */ 32658d7027bSFrank Praznik 0x95, 0x39, /* Report Count (57), */ 32758d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 32858d7027bSFrank Praznik 0x85, 0xAD, /* Report ID (173), */ 32958d7027bSFrank Praznik 0x09, 0x51, /* Usage (51h), */ 33058d7027bSFrank Praznik 0x95, 0x0B, /* Report Count (11), */ 33158d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33258d7027bSFrank Praznik 0x85, 0xAE, /* Report ID (174), */ 33358d7027bSFrank Praznik 0x09, 0x52, /* Usage (52h), */ 33458d7027bSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 33558d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 33658d7027bSFrank Praznik 0x85, 0xAF, /* Report ID (175), */ 33758d7027bSFrank Praznik 0x09, 0x53, /* Usage (53h), */ 33858d7027bSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 33958d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34058d7027bSFrank Praznik 0x85, 0xB0, /* Report ID (176), */ 34158d7027bSFrank Praznik 0x09, 0x54, /* Usage (54h), */ 34258d7027bSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 34358d7027bSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 34458d7027bSFrank Praznik 0xC0 /* End Collection */ 345ed19d8cfSFrank Praznik }; 346ed19d8cfSFrank Praznik 347ad142b9eSFrank Praznik /* 348ad142b9eSFrank Praznik * The default behavior of the Dualshock 4 is to send reports using report 349d829674dSFrank Praznik * type 1 when running over Bluetooth. However, as soon as it receives a 350d829674dSFrank Praznik * report of type 17 to set the LEDs or rumble it starts returning it's state 351d829674dSFrank Praznik * in report 17 instead of 1. Since report 17 is undefined in the default HID 352d829674dSFrank Praznik * descriptor the button and axis definitions must be moved to report 17 or 353d829674dSFrank Praznik * the HID layer won't process the received input once a report is sent. 354d829674dSFrank Praznik */ 355d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = { 356d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 357d829674dSFrank Praznik 0x09, 0x05, /* Usage (Gamepad), */ 358d829674dSFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 359d829674dSFrank Praznik 0x85, 0x01, /* Report ID (1), */ 360d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 361d829674dSFrank Praznik 0x95, 0x0A, /* Report Count (9), */ 362d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 363d829674dSFrank Praznik 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ 364d829674dSFrank Praznik 0x85, 0x02, /* Report ID (2), */ 365d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 366d829674dSFrank Praznik 0x95, 0x24, /* Report Count (36), */ 367d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 368d829674dSFrank Praznik 0x85, 0xA3, /* Report ID (163), */ 369d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 370d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 371d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 372d829674dSFrank Praznik 0x85, 0x05, /* Report ID (5), */ 373d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 374d829674dSFrank Praznik 0x95, 0x28, /* Report Count (40), */ 375d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 376d829674dSFrank Praznik 0x85, 0x06, /* Report ID (6), */ 377d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 378d829674dSFrank Praznik 0x95, 0x34, /* Report Count (52), */ 379d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 380d829674dSFrank Praznik 0x85, 0x07, /* Report ID (7), */ 381d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 382d829674dSFrank Praznik 0x95, 0x30, /* Report Count (48), */ 383d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 384d829674dSFrank Praznik 0x85, 0x08, /* Report ID (8), */ 385d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 386d829674dSFrank Praznik 0x95, 0x2F, /* Report Count (47), */ 387d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 388d829674dSFrank Praznik 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ 389d829674dSFrank Praznik 0x85, 0x03, /* Report ID (3), */ 390d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 391d829674dSFrank Praznik 0x95, 0x26, /* Report Count (38), */ 392d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 393d829674dSFrank Praznik 0x85, 0x04, /* Report ID (4), */ 394d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 395d829674dSFrank Praznik 0x95, 0x2E, /* Report Count (46), */ 396d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 397d829674dSFrank Praznik 0x85, 0xF0, /* Report ID (240), */ 398d829674dSFrank Praznik 0x09, 0x47, /* Usage (47h), */ 399d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 400d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 401d829674dSFrank Praznik 0x85, 0xF1, /* Report ID (241), */ 402d829674dSFrank Praznik 0x09, 0x48, /* Usage (48h), */ 403d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 404d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 405d829674dSFrank Praznik 0x85, 0xF2, /* Report ID (242), */ 406d829674dSFrank Praznik 0x09, 0x49, /* Usage (49h), */ 407d829674dSFrank Praznik 0x95, 0x0F, /* Report Count (15), */ 408d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 409d829674dSFrank Praznik 0x85, 0x11, /* Report ID (17), */ 410d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 411d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 412d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 413d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 414d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 415d829674dSFrank Praznik 0x09, 0x30, /* Usage (X), */ 416d829674dSFrank Praznik 0x09, 0x31, /* Usage (Y), */ 417d829674dSFrank Praznik 0x09, 0x32, /* Usage (Z), */ 418d829674dSFrank Praznik 0x09, 0x35, /* Usage (Rz), */ 419d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 420d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 421d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 422d829674dSFrank Praznik 0x95, 0x04, /* Report Count (4), */ 423d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 424d829674dSFrank Praznik 0x09, 0x39, /* Usage (Hat Switch), */ 425d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 426d829674dSFrank Praznik 0x25, 0x07, /* Logical Maximum (7), */ 427d829674dSFrank Praznik 0x75, 0x04, /* Report Size (4), */ 428d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 429d829674dSFrank Praznik 0x81, 0x42, /* Input (Variable, Null State), */ 430d829674dSFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 431d829674dSFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 432d829674dSFrank Praznik 0x29, 0x0E, /* Usage Maximum (0Eh), */ 433d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 434d829674dSFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 435d829674dSFrank Praznik 0x75, 0x01, /* Report Size (1), */ 436d829674dSFrank Praznik 0x95, 0x0E, /* Report Count (14), */ 437d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 438d829674dSFrank Praznik 0x75, 0x06, /* Report Size (6), */ 439d829674dSFrank Praznik 0x95, 0x01, /* Report Count (1), */ 440d829674dSFrank Praznik 0x81, 0x01, /* Input (Constant), */ 441d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 442d829674dSFrank Praznik 0x09, 0x33, /* Usage (Rx), */ 443d829674dSFrank Praznik 0x09, 0x34, /* Usage (Ry), */ 444d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 445d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 446d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 447d829674dSFrank Praznik 0x95, 0x02, /* Report Count (2), */ 448d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 449d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 450d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 451d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 452d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 453d829674dSFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 454d829674dSFrank Praznik 0x19, 0x40, /* Usage Minimum (40h), */ 455d829674dSFrank Praznik 0x29, 0x42, /* Usage Maximum (42h), */ 456d829674dSFrank Praznik 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ 457d829674dSFrank Praznik 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ 458d829674dSFrank Praznik 0x75, 0x10, /* Report Size (16), */ 459d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 460d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 461d829674dSFrank Praznik 0x19, 0x43, /* Usage Minimum (43h), */ 462d829674dSFrank Praznik 0x29, 0x45, /* Usage Maximum (45h), */ 463d829674dSFrank Praznik 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ 464d829674dSFrank Praznik 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ 465d829674dSFrank Praznik 0x95, 0x03, /* Report Count (3), */ 466d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 467d829674dSFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 468d829674dSFrank Praznik 0x09, 0x20, /* Usage (20h), */ 469d829674dSFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 470d829674dSFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 471d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 472d829674dSFrank Praznik 0x95, 0x31, /* Report Count (51), */ 473d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 474d829674dSFrank Praznik 0x09, 0x21, /* Usage (21h), */ 475d829674dSFrank Praznik 0x75, 0x08, /* Report Size (8), */ 476d829674dSFrank Praznik 0x95, 0x4D, /* Report Count (77), */ 477d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 478d829674dSFrank Praznik 0x85, 0x12, /* Report ID (18), */ 479d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 480d829674dSFrank Praznik 0x95, 0x8D, /* Report Count (141), */ 481d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 482d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 483d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 484d829674dSFrank Praznik 0x85, 0x13, /* Report ID (19), */ 485d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 486d829674dSFrank Praznik 0x95, 0xCD, /* Report Count (205), */ 487d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 488d829674dSFrank Praznik 0x09, 0x25, /* Usage (25h), */ 489d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 490d829674dSFrank Praznik 0x85, 0x14, /* Report ID (20), */ 491d829674dSFrank Praznik 0x09, 0x26, /* Usage (26h), */ 492d829674dSFrank Praznik 0x96, 0x0D, 0x01, /* Report Count (269), */ 493d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 494d829674dSFrank Praznik 0x09, 0x27, /* Usage (27h), */ 495d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 496d829674dSFrank Praznik 0x85, 0x15, /* Report ID (21), */ 497d829674dSFrank Praznik 0x09, 0x28, /* Usage (28h), */ 498d829674dSFrank Praznik 0x96, 0x4D, 0x01, /* Report Count (333), */ 499d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 500d829674dSFrank Praznik 0x09, 0x29, /* Usage (29h), */ 501d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 502d829674dSFrank Praznik 0x85, 0x16, /* Report ID (22), */ 503d829674dSFrank Praznik 0x09, 0x2A, /* Usage (2Ah), */ 504d829674dSFrank Praznik 0x96, 0x8D, 0x01, /* Report Count (397), */ 505d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 506d829674dSFrank Praznik 0x09, 0x2B, /* Usage (2Bh), */ 507d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 508d829674dSFrank Praznik 0x85, 0x17, /* Report ID (23), */ 509d829674dSFrank Praznik 0x09, 0x2C, /* Usage (2Ch), */ 510d829674dSFrank Praznik 0x96, 0xCD, 0x01, /* Report Count (461), */ 511d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 512d829674dSFrank Praznik 0x09, 0x2D, /* Usage (2Dh), */ 513d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 514d829674dSFrank Praznik 0x85, 0x18, /* Report ID (24), */ 515d829674dSFrank Praznik 0x09, 0x2E, /* Usage (2Eh), */ 516d829674dSFrank Praznik 0x96, 0x0D, 0x02, /* Report Count (525), */ 517d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 518d829674dSFrank Praznik 0x09, 0x2F, /* Usage (2Fh), */ 519d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 520d829674dSFrank Praznik 0x85, 0x19, /* Report ID (25), */ 521d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 522d829674dSFrank Praznik 0x96, 0x22, 0x02, /* Report Count (546), */ 523d829674dSFrank Praznik 0x81, 0x02, /* Input (Variable), */ 524d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 525d829674dSFrank Praznik 0x91, 0x02, /* Output (Variable), */ 526d829674dSFrank Praznik 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ 527d829674dSFrank Praznik 0x85, 0x82, /* Report ID (130), */ 528d829674dSFrank Praznik 0x09, 0x22, /* Usage (22h), */ 529d829674dSFrank Praznik 0x95, 0x3F, /* Report Count (63), */ 530d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 531d829674dSFrank Praznik 0x85, 0x83, /* Report ID (131), */ 532d829674dSFrank Praznik 0x09, 0x23, /* Usage (23h), */ 533d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 534d829674dSFrank Praznik 0x85, 0x84, /* Report ID (132), */ 535d829674dSFrank Praznik 0x09, 0x24, /* Usage (24h), */ 536d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 537d829674dSFrank Praznik 0x85, 0x90, /* Report ID (144), */ 538d829674dSFrank Praznik 0x09, 0x30, /* Usage (30h), */ 539d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 540d829674dSFrank Praznik 0x85, 0x91, /* Report ID (145), */ 541d829674dSFrank Praznik 0x09, 0x31, /* Usage (31h), */ 542d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 543d829674dSFrank Praznik 0x85, 0x92, /* Report ID (146), */ 544d829674dSFrank Praznik 0x09, 0x32, /* Usage (32h), */ 545d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 546d829674dSFrank Praznik 0x85, 0x93, /* Report ID (147), */ 547d829674dSFrank Praznik 0x09, 0x33, /* Usage (33h), */ 548d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 549d829674dSFrank Praznik 0x85, 0xA0, /* Report ID (160), */ 550d829674dSFrank Praznik 0x09, 0x40, /* Usage (40h), */ 551d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 552d829674dSFrank Praznik 0x85, 0xA4, /* Report ID (164), */ 553d829674dSFrank Praznik 0x09, 0x44, /* Usage (44h), */ 554d829674dSFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 555d829674dSFrank Praznik 0xC0 /* End Collection */ 556d829674dSFrank Praznik }; 557d829674dSFrank Praznik 558078328daSJiri Kosina static __u8 ps3remote_rdesc[] = { 559078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 560078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 561078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 562078328daSJiri Kosina 563078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 564078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 565078328daSJiri Kosina 566078328daSJiri Kosina /* Ignore the 1st byte, maybe it is used for a controller 567078328daSJiri Kosina * number but it's not needed for correct operation */ 568078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 569078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 570078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 571078328daSJiri Kosina 572078328daSJiri Kosina /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 573078328daSJiri Kosina * buttons multiple keypresses are allowed */ 574078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 575078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 576078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 577078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 578078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 579078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 580078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 581078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 582078328daSJiri Kosina 583078328daSJiri Kosina 0xC0, /* MEndCollection */ 584078328daSJiri Kosina 585078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 586078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 587078328daSJiri Kosina 588078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 589078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 590078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 591078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 592078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 593078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 594078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 595078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 596078328daSJiri Kosina 0x80, /* MInput */ 597078328daSJiri Kosina 598078328daSJiri Kosina /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at 599078328daSJiri Kosina * 0xff and 11th is for press indication */ 600078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 601078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 602078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 603078328daSJiri Kosina 604078328daSJiri Kosina /* 12th byte is for battery strength */ 605078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 606078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 607078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 608078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 609078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 610078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 611078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 612078328daSJiri Kosina 613078328daSJiri Kosina 0xC0, /* MEndCollection */ 614078328daSJiri Kosina 615078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 616078328daSJiri Kosina }; 617078328daSJiri Kosina 618078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 619078328daSJiri Kosina [0x01] = KEY_SELECT, 620078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 621078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 622078328daSJiri Kosina [0x04] = BTN_START, 623078328daSJiri Kosina [0x05] = KEY_UP, 624078328daSJiri Kosina [0x06] = KEY_RIGHT, 625078328daSJiri Kosina [0x07] = KEY_DOWN, 626078328daSJiri Kosina [0x08] = KEY_LEFT, 627078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 628078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 629078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 630078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 631078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 632078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 633078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 634078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 635078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 636078328daSJiri Kosina [0x14] = KEY_ENTER, 637078328daSJiri Kosina }; 638078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 639078328daSJiri Kosina [0x00] = KEY_1, 640078328daSJiri Kosina [0x01] = KEY_2, 641078328daSJiri Kosina [0x02] = KEY_3, 642078328daSJiri Kosina [0x03] = KEY_4, 643078328daSJiri Kosina [0x04] = KEY_5, 644078328daSJiri Kosina [0x05] = KEY_6, 645078328daSJiri Kosina [0x06] = KEY_7, 646078328daSJiri Kosina [0x07] = KEY_8, 647078328daSJiri Kosina [0x08] = KEY_9, 648078328daSJiri Kosina [0x09] = KEY_0, 649078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 650078328daSJiri Kosina [0x0f] = KEY_CLEAR, 651078328daSJiri Kosina [0x16] = KEY_EJECTCD, 652078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 653078328daSJiri Kosina [0x28] = KEY_TIME, 654078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 655078328daSJiri Kosina [0x31] = KEY_NEXT, 656078328daSJiri Kosina [0x32] = KEY_PLAY, 657078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 658078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 659078328daSJiri Kosina [0x38] = KEY_STOP, 660078328daSJiri Kosina [0x39] = KEY_PAUSE, 661078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 662078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 663078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 664078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 665078328daSJiri Kosina [0x64] = KEY_AUDIO, 666078328daSJiri Kosina [0x65] = KEY_ANGLE, 667078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 668078328daSJiri Kosina [0x80] = KEY_BLUE, 669078328daSJiri Kosina [0x81] = KEY_RED, 670078328daSJiri Kosina [0x82] = KEY_GREEN, 671078328daSJiri Kosina [0x83] = KEY_YELLOW, 672078328daSJiri Kosina }; 673078328daSJiri Kosina 674f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 675ad142b9eSFrank Praznik /* 676ad142b9eSFrank Praznik * The controller has 4 remote buzzers, each with one LED and 5 677f04d5140SColin Leitner * buttons. 678f04d5140SColin Leitner * 679f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 680f04d5140SColin Leitner * 681f04d5140SColin Leitner * Key Offset 682f04d5140SColin Leitner * ------------------- 683f04d5140SColin Leitner * Buzz 1 684f04d5140SColin Leitner * Blue 5 685f04d5140SColin Leitner * Orange 4 686f04d5140SColin Leitner * Green 3 687f04d5140SColin Leitner * Yellow 2 688f04d5140SColin Leitner * 689f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 690f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 691f04d5140SColin Leitner */ 692f04d5140SColin Leitner [ 1] = BTN_TRIGGER_HAPPY1, 693f04d5140SColin Leitner [ 2] = BTN_TRIGGER_HAPPY2, 694f04d5140SColin Leitner [ 3] = BTN_TRIGGER_HAPPY3, 695f04d5140SColin Leitner [ 4] = BTN_TRIGGER_HAPPY4, 696f04d5140SColin Leitner [ 5] = BTN_TRIGGER_HAPPY5, 697f04d5140SColin Leitner [ 6] = BTN_TRIGGER_HAPPY6, 698f04d5140SColin Leitner [ 7] = BTN_TRIGGER_HAPPY7, 699f04d5140SColin Leitner [ 8] = BTN_TRIGGER_HAPPY8, 700f04d5140SColin Leitner [ 9] = BTN_TRIGGER_HAPPY9, 701f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 702f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 703f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 704f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 705f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 706f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 707f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 708f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 709f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 710f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 711f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 712f04d5140SColin Leitner }; 713f04d5140SColin Leitner 714d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = { 715d902f472SFrank Praznik POWER_SUPPLY_PROP_PRESENT, 716d902f472SFrank Praznik POWER_SUPPLY_PROP_CAPACITY, 717d902f472SFrank Praznik POWER_SUPPLY_PROP_SCOPE, 718d902f472SFrank Praznik POWER_SUPPLY_PROP_STATUS, 719d902f472SFrank Praznik }; 720d902f472SFrank Praznik 72155d3b664SFrank Praznik struct sixaxis_led { 72255d3b664SFrank Praznik __u8 time_enabled; /* the total time the led is active (0xff means forever) */ 72355d3b664SFrank Praznik __u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ 72455d3b664SFrank Praznik __u8 enabled; 72555d3b664SFrank Praznik __u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ 72655d3b664SFrank Praznik __u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ 72755d3b664SFrank Praznik } __packed; 72855d3b664SFrank Praznik 72955d3b664SFrank Praznik struct sixaxis_rumble { 73055d3b664SFrank Praznik __u8 padding; 73155d3b664SFrank Praznik __u8 right_duration; /* Right motor duration (0xff means forever) */ 73255d3b664SFrank Praznik __u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ 73355d3b664SFrank Praznik __u8 left_duration; /* Left motor duration (0xff means forever) */ 73455d3b664SFrank Praznik __u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ 73555d3b664SFrank Praznik } __packed; 73655d3b664SFrank Praznik 73755d3b664SFrank Praznik struct sixaxis_output_report { 73855d3b664SFrank Praznik __u8 report_id; 73955d3b664SFrank Praznik struct sixaxis_rumble rumble; 74055d3b664SFrank Praznik __u8 padding[4]; 74155d3b664SFrank Praznik __u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ 74255d3b664SFrank Praznik struct sixaxis_led led[4]; /* LEDx at (4 - x) */ 74355d3b664SFrank Praznik struct sixaxis_led _reserved; /* LED5, not actually soldered */ 74455d3b664SFrank Praznik } __packed; 74555d3b664SFrank Praznik 74655d3b664SFrank Praznik union sixaxis_output_report_01 { 74755d3b664SFrank Praznik struct sixaxis_output_report data; 74855d3b664SFrank Praznik __u8 buf[36]; 74955d3b664SFrank Praznik }; 75055d3b664SFrank Praznik 751d2d782fcSFrank Praznik static spinlock_t sony_dev_list_lock; 752d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list); 7538025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator); 754d2d782fcSFrank Praznik 755cc6e0bbbSJiri Kosina struct sony_sc { 756d902f472SFrank Praznik spinlock_t lock; 757d2d782fcSFrank Praznik struct list_head list_node; 7580a286ef2SSven Eckelmann struct hid_device *hdev; 75960781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 760cc6e0bbbSJiri Kosina unsigned long quirks; 7610a286ef2SSven Eckelmann struct work_struct state_worker; 762d902f472SFrank Praznik struct power_supply battery; 7638025087aSFrank Praznik int device_id; 764f04d5140SColin Leitner 7659f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 7669f323b68SSven Eckelmann __u8 left; 7679f323b68SSven Eckelmann __u8 right; 7689f323b68SSven Eckelmann #endif 7699f323b68SSven Eckelmann 770d2d782fcSFrank Praznik __u8 mac_address[6]; 7715f5750d2SFrank Praznik __u8 worker_initialized; 772d902f472SFrank Praznik __u8 cable_state; 773d902f472SFrank Praznik __u8 battery_charging; 774d902f472SFrank Praznik __u8 battery_capacity; 77560781cf4SFrank Praznik __u8 led_state[MAX_LEDS]; 776b3ed458cSFrank Praznik __u8 led_delay_on[MAX_LEDS]; 777b3ed458cSFrank Praznik __u8 led_delay_off[MAX_LEDS]; 77860781cf4SFrank Praznik __u8 led_count; 779cc6e0bbbSJiri Kosina }; 780cc6e0bbbSJiri Kosina 781078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 782078328daSJiri Kosina unsigned int *rsize) 783078328daSJiri Kosina { 784078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 785078328daSJiri Kosina return ps3remote_rdesc; 786078328daSJiri Kosina } 787078328daSJiri Kosina 788078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 789078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 790078328daSJiri Kosina unsigned long **bit, int *max) 791078328daSJiri Kosina { 792078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 793078328daSJiri Kosina 794078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 795078328daSJiri Kosina return -1; 796078328daSJiri Kosina 797078328daSJiri Kosina switch (usage->collection_index) { 798078328daSJiri Kosina case 1: 799078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 800078328daSJiri Kosina return -1; 801078328daSJiri Kosina 802078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 803078328daSJiri Kosina if (!key) 804078328daSJiri Kosina return -1; 805078328daSJiri Kosina break; 806078328daSJiri Kosina case 2: 807078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 808078328daSJiri Kosina return -1; 809078328daSJiri Kosina 810078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 811078328daSJiri Kosina if (!key) 812078328daSJiri Kosina return -1; 813078328daSJiri Kosina break; 814078328daSJiri Kosina default: 815078328daSJiri Kosina return -1; 816078328daSJiri Kosina } 817078328daSJiri Kosina 818078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 819078328daSJiri Kosina return 1; 820078328daSJiri Kosina } 821078328daSJiri Kosina 822078328daSJiri Kosina 823cc6e0bbbSJiri Kosina /* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 82473e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 82573e4008dSNikolai Kondrashov unsigned int *rsize) 826cc6e0bbbSJiri Kosina { 827cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 828cc6e0bbbSJiri Kosina 82999d24902SFernando Luis Vázquez Cao /* 83099d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 83199d24902SFernando Luis Vázquez Cao * a constant non-data variable. 83299d24902SFernando Luis Vázquez Cao */ 83399d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 83499d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 83599d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 83699d24902SFernando Luis Vázquez Cao /* usage: mouse */ 83799d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 83899d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 83999d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 840a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 84199d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 842cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 843cc6e0bbbSJiri Kosina } 84461ab44beSSimon Wood 845ed19d8cfSFrank Praznik /* 846ed19d8cfSFrank Praznik * The default Dualshock 4 USB descriptor doesn't assign 847ed19d8cfSFrank Praznik * the gyroscope values to corresponding axes so we need a 848ed19d8cfSFrank Praznik * modified one. 849ed19d8cfSFrank Praznik */ 850ed19d8cfSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) { 851ed19d8cfSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 852ed19d8cfSFrank Praznik rdesc = dualshock4_usb_rdesc; 853ed19d8cfSFrank Praznik *rsize = sizeof(dualshock4_usb_rdesc); 854d829674dSFrank Praznik } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { 855d829674dSFrank Praznik hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); 856d829674dSFrank Praznik rdesc = dualshock4_bt_rdesc; 857d829674dSFrank Praznik *rsize = sizeof(dualshock4_bt_rdesc); 858ed19d8cfSFrank Praznik } 859ed19d8cfSFrank Praznik 86061ab44beSSimon Wood /* The HID descriptor exposed over BT has a trailing zero byte */ 86161ab44beSSimon Wood if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 86261ab44beSSimon Wood ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) && 86361ab44beSSimon Wood rdesc[83] == 0x75) { 86461ab44beSSimon Wood hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); 86561ab44beSSimon Wood memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, 86661ab44beSSimon Wood sizeof(sixaxis_rdesc_fixup)); 867e57a67daSMauro Carvalho Chehab } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && 868e57a67daSMauro Carvalho Chehab *rsize > sizeof(sixaxis_rdesc_fixup2)) { 869e57a67daSMauro Carvalho Chehab hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", 870e57a67daSMauro Carvalho Chehab *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); 871e57a67daSMauro Carvalho Chehab *rsize = sizeof(sixaxis_rdesc_fixup2); 872e57a67daSMauro Carvalho Chehab memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); 87361ab44beSSimon Wood } 874078328daSJiri Kosina 875078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 876078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 877078328daSJiri Kosina 87873e4008dSNikolai Kondrashov return rdesc; 879cc6e0bbbSJiri Kosina } 880cc6e0bbbSJiri Kosina 881d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) 882d902f472SFrank Praznik { 883d902f472SFrank Praznik static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 884d902f472SFrank Praznik unsigned long flags; 885d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 886d902f472SFrank Praznik 887ad142b9eSFrank Praznik /* 888ad142b9eSFrank Praznik * The sixaxis is charging if the battery value is 0xee 889d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 890d902f472SFrank Praznik * It does not report the actual level while charging so it 891d902f472SFrank Praznik * is set to 100% while charging is in progress. 892d902f472SFrank Praznik */ 893d902f472SFrank Praznik if (rd[30] >= 0xee) { 894d902f472SFrank Praznik battery_capacity = 100; 895a43e94a3SFrank Praznik battery_charging = !(rd[30] & 0x01); 896d902f472SFrank Praznik } else { 897ac3c9a94SFrank Praznik __u8 index = rd[30] <= 5 ? rd[30] : 5; 898ac3c9a94SFrank Praznik battery_capacity = sixaxis_battery_capacity[index]; 899d902f472SFrank Praznik battery_charging = 0; 900d902f472SFrank Praznik } 901914c5783SFrank Praznik cable_state = !(rd[31] & 0x04); 902d902f472SFrank Praznik 903d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 904d902f472SFrank Praznik sc->cable_state = cable_state; 905d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 906d902f472SFrank Praznik sc->battery_charging = battery_charging; 907d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 908d902f472SFrank Praznik } 909d902f472SFrank Praznik 910d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) 911d902f472SFrank Praznik { 912e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 913e5606230SFrank Praznik struct hid_input, list); 914e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 915d902f472SFrank Praznik unsigned long flags; 9166c5f860dSFrank Praznik int n, offset; 917d902f472SFrank Praznik __u8 cable_state, battery_capacity, battery_charging; 918d902f472SFrank Praznik 919ad142b9eSFrank Praznik /* 920ad142b9eSFrank Praznik * Battery and touchpad data starts at byte 30 in the USB report and 9216c5f860dSFrank Praznik * 32 in Bluetooth report. 9226c5f860dSFrank Praznik */ 9236c5f860dSFrank Praznik offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; 9246c5f860dSFrank Praznik 925ad142b9eSFrank Praznik /* 926ad142b9eSFrank Praznik * The lower 4 bits of byte 30 contain the battery level 927d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 928d902f472SFrank Praznik */ 9296c5f860dSFrank Praznik cable_state = (rd[offset] >> 4) & 0x01; 9306c5f860dSFrank Praznik battery_capacity = rd[offset] & 0x0F; 931d902f472SFrank Praznik 932ad142b9eSFrank Praznik /* 933ad142b9eSFrank Praznik * When a USB power source is connected the battery level ranges from 9346c5f860dSFrank Praznik * 0 to 10, and when running on battery power it ranges from 0 to 9. 9356c5f860dSFrank Praznik * A battery level above 10 when plugged in means charge completed. 936d902f472SFrank Praznik */ 9376c5f860dSFrank Praznik if (!cable_state || battery_capacity > 10) 938d902f472SFrank Praznik battery_charging = 0; 939d902f472SFrank Praznik else 940d902f472SFrank Praznik battery_charging = 1; 941d902f472SFrank Praznik 9426c5f860dSFrank Praznik if (!cable_state) 9436c5f860dSFrank Praznik battery_capacity++; 944d902f472SFrank Praznik if (battery_capacity > 10) 9456c5f860dSFrank Praznik battery_capacity = 10; 9466c5f860dSFrank Praznik 947d902f472SFrank Praznik battery_capacity *= 10; 948d902f472SFrank Praznik 949d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 950d902f472SFrank Praznik sc->cable_state = cable_state; 951d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 952d902f472SFrank Praznik sc->battery_charging = battery_charging; 953d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 954e5606230SFrank Praznik 9556c5f860dSFrank Praznik offset += 5; 9566c5f860dSFrank Praznik 957ad142b9eSFrank Praznik /* 958ad142b9eSFrank Praznik * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB 9596c5f860dSFrank Praznik * and 37 on Bluetooth. 960e5606230SFrank Praznik * The first 7 bits of the first byte is a counter and bit 8 is a touch 961e5606230SFrank Praznik * indicator that is 0 when pressed and 1 when not pressed. 962e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 963e5606230SFrank Praznik * The data for the second touch is in the same format and immediatly 964e5606230SFrank Praznik * follows the data for the first. 965e5606230SFrank Praznik */ 966e5606230SFrank Praznik for (n = 0; n < 2; n++) { 967e5606230SFrank Praznik __u16 x, y; 968e5606230SFrank Praznik 969e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 970e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 971e5606230SFrank Praznik 972e5606230SFrank Praznik input_mt_slot(input_dev, n); 973e5606230SFrank Praznik input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 974e5606230SFrank Praznik !(rd[offset] >> 7)); 975e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_X, x); 976e5606230SFrank Praznik input_report_abs(input_dev, ABS_MT_POSITION_Y, y); 977e5606230SFrank Praznik 978e5606230SFrank Praznik offset += 4; 979e5606230SFrank Praznik } 980d902f472SFrank Praznik } 981d902f472SFrank Praznik 982c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 983c9e4d877SSimon Wood __u8 *rd, int size) 984c9e4d877SSimon Wood { 985c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 986c9e4d877SSimon Wood 987ad142b9eSFrank Praznik /* 988ad142b9eSFrank Praznik * Sixaxis HID report has acclerometers/gyro with MSByte first, this 989c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 990c9e4d877SSimon Wood */ 991fee4e2d5SFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { 992c9e4d877SSimon Wood swap(rd[41], rd[42]); 993c9e4d877SSimon Wood swap(rd[43], rd[44]); 994c9e4d877SSimon Wood swap(rd[45], rd[46]); 995c9e4d877SSimon Wood swap(rd[47], rd[48]); 996d902f472SFrank Praznik 997d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 99868330d83SFrank Praznik } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 99968330d83SFrank Praznik size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) 100068330d83SFrank Praznik && rd[0] == 0x11 && size == 78)) { 1001d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 1002c9e4d877SSimon Wood } 1003c9e4d877SSimon Wood 1004c9e4d877SSimon Wood return 0; 1005c9e4d877SSimon Wood } 1006c9e4d877SSimon Wood 1007f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 1008f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 1009f04d5140SColin Leitner unsigned long **bit, int *max) 1010f04d5140SColin Leitner { 1011f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1012f04d5140SColin Leitner 1013f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 1014f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 1015f04d5140SColin Leitner 1016f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 1017f04d5140SColin Leitner return -1; 1018f04d5140SColin Leitner 1019f04d5140SColin Leitner switch (usage->collection_index) { 1020f04d5140SColin Leitner case 1: 1021f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 1022f04d5140SColin Leitner return -1; 1023f04d5140SColin Leitner 1024f04d5140SColin Leitner key = buzz_keymap[key]; 1025f04d5140SColin Leitner if (!key) 1026f04d5140SColin Leitner return -1; 1027f04d5140SColin Leitner break; 1028f04d5140SColin Leitner default: 1029f04d5140SColin Leitner return -1; 1030f04d5140SColin Leitner } 1031f04d5140SColin Leitner 1032f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 1033f04d5140SColin Leitner return 1; 1034f04d5140SColin Leitner } 1035f04d5140SColin Leitner 1036078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 1037078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 1038078328daSJiri Kosina 10396f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 10406f498018SBenjamin Tissoires return 0; 1041f04d5140SColin Leitner } 1042f04d5140SColin Leitner 10435710fabfSAntonio Ospite /* 1044bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1045bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1046bd28ce00SJiri Slaby * events. 1047bd28ce00SJiri Slaby */ 1048816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1049bd28ce00SJiri Slaby { 1050bd28ce00SJiri Slaby int ret; 1051bd28ce00SJiri Slaby char *buf = kmalloc(18, GFP_KERNEL); 1052bd28ce00SJiri Slaby 1053bd28ce00SJiri Slaby if (!buf) 1054bd28ce00SJiri Slaby return -ENOMEM; 1055bd28ce00SJiri Slaby 1056cafebc05SBenjamin Tissoires ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, 1057cafebc05SBenjamin Tissoires HID_REQ_GET_REPORT); 1058f204828aSBenjamin Tissoires 1059bd28ce00SJiri Slaby if (ret < 0) 10604291ee30SJoe Perches hid_err(hdev, "can't set operational mode\n"); 1061bd28ce00SJiri Slaby 1062bd28ce00SJiri Slaby kfree(buf); 1063bd28ce00SJiri Slaby 1064bd28ce00SJiri Slaby return ret; 1065bd28ce00SJiri Slaby } 1066bd28ce00SJiri Slaby 1067816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1068f9ce7c28SBastien Nocera { 1069fddb33f2SAntonio Ospite unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 1070b0dd72aaSBenjamin Tissoires return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf), 1071b0dd72aaSBenjamin Tissoires HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 1072f9ce7c28SBastien Nocera } 1073f9ce7c28SBastien Nocera 1074ad142b9eSFrank Praznik /* 1075ad142b9eSFrank Praznik * Requesting feature report 0x02 in Bluetooth mode changes the state of the 107668330d83SFrank Praznik * controller so that it sends full input reports of type 0x11. 107768330d83SFrank Praznik */ 107868330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev) 107968330d83SFrank Praznik { 108068330d83SFrank Praznik __u8 buf[37] = { 0 }; 108168330d83SFrank Praznik 108268330d83SFrank Praznik return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf), 108368330d83SFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1084bd28ce00SJiri Slaby } 1085bd28ce00SJiri Slaby 10868025087aSFrank Praznik static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 10878025087aSFrank Praznik { 10888025087aSFrank Praznik static const __u8 sixaxis_leds[10][4] = { 10898025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x00 }, 10908025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x00 }, 10918025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x00 }, 10928025087aSFrank Praznik { 0x00, 0x00, 0x00, 0x01 }, 10938025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x01 }, 10948025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x01 }, 10958025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x01 }, 10968025087aSFrank Praznik { 0x01, 0x00, 0x01, 0x01 }, 10978025087aSFrank Praznik { 0x00, 0x01, 0x01, 0x01 }, 10988025087aSFrank Praznik { 0x01, 0x01, 0x01, 0x01 } 10998025087aSFrank Praznik }; 11008025087aSFrank Praznik 11018025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0])); 11028025087aSFrank Praznik 11038025087aSFrank Praznik if (id < 0) 11048025087aSFrank Praznik return; 11058025087aSFrank Praznik 11068025087aSFrank Praznik id %= 10; 11078025087aSFrank Praznik memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id])); 11088025087aSFrank Praznik } 11098025087aSFrank Praznik 11108025087aSFrank Praznik static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS]) 11118025087aSFrank Praznik { 11128025087aSFrank Praznik /* The first 4 color/index entries match what the PS4 assigns */ 11138025087aSFrank Praznik static const __u8 color_code[7][3] = { 11148025087aSFrank Praznik /* Blue */ { 0x00, 0x00, 0x01 }, 11158025087aSFrank Praznik /* Red */ { 0x01, 0x00, 0x00 }, 11168025087aSFrank Praznik /* Green */ { 0x00, 0x01, 0x00 }, 11178025087aSFrank Praznik /* Pink */ { 0x02, 0x00, 0x01 }, 11188025087aSFrank Praznik /* Orange */ { 0x02, 0x01, 0x00 }, 11198025087aSFrank Praznik /* Teal */ { 0x00, 0x01, 0x01 }, 11208025087aSFrank Praznik /* White */ { 0x01, 0x01, 0x01 } 11218025087aSFrank Praznik }; 11228025087aSFrank Praznik 11238025087aSFrank Praznik BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0])); 11248025087aSFrank Praznik 11258025087aSFrank Praznik if (id < 0) 11268025087aSFrank Praznik return; 11278025087aSFrank Praznik 11288025087aSFrank Praznik id %= 7; 11298025087aSFrank Praznik memcpy(values, color_code[id], sizeof(color_code[id])); 11308025087aSFrank Praznik } 11318025087aSFrank Praznik 113260781cf4SFrank Praznik static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds) 1133f04d5140SColin Leitner { 1134f04d5140SColin Leitner struct list_head *report_list = 1135f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1136f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1137f04d5140SColin Leitner struct hid_report, list); 1138f04d5140SColin Leitner __s32 *value = report->field[0]->value; 1139f04d5140SColin Leitner 1140f04d5140SColin Leitner value[0] = 0x00; 114160781cf4SFrank Praznik value[1] = leds[0] ? 0xff : 0x00; 114260781cf4SFrank Praznik value[2] = leds[1] ? 0xff : 0x00; 114360781cf4SFrank Praznik value[3] = leds[2] ? 0xff : 0x00; 114460781cf4SFrank Praznik value[4] = leds[3] ? 0xff : 0x00; 1145f04d5140SColin Leitner value[5] = 0x00; 1146f04d5140SColin Leitner value[6] = 0x00; 1147f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1148f04d5140SColin Leitner } 1149f04d5140SColin Leitner 1150fa57a810SFrank Praznik static void sony_set_leds(struct sony_sc *sc, const __u8 *leds, int count) 11510a286ef2SSven Eckelmann { 115260781cf4SFrank Praznik int n; 11530a286ef2SSven Eckelmann 115460781cf4SFrank Praznik BUG_ON(count > MAX_LEDS); 115560781cf4SFrank Praznik 1156fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER && count == 4) { 1157fa57a810SFrank Praznik buzz_set_leds(sc->hdev, leds); 1158fee4e2d5SFrank Praznik } else { 115960781cf4SFrank Praznik for (n = 0; n < count; n++) 1160fa57a810SFrank Praznik sc->led_state[n] = leds[n]; 1161fa57a810SFrank Praznik schedule_work(&sc->state_worker); 11620a286ef2SSven Eckelmann } 11630a286ef2SSven Eckelmann } 11640a286ef2SSven Eckelmann 1165c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1166f04d5140SColin Leitner enum led_brightness value) 1167f04d5140SColin Leitner { 1168f04d5140SColin Leitner struct device *dev = led->dev->parent; 1169f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1170f04d5140SColin Leitner struct sony_sc *drv_data; 1171f04d5140SColin Leitner 1172f04d5140SColin Leitner int n; 1173b3ed458cSFrank Praznik int force_update; 1174f04d5140SColin Leitner 1175f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 11762251b85fSSven Eckelmann if (!drv_data) { 1177f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1178f04d5140SColin Leitner return; 1179f04d5140SColin Leitner } 1180f04d5140SColin Leitner 1181b3ed458cSFrank Praznik /* 1182b3ed458cSFrank Praznik * The Sixaxis on USB will override any LED settings sent to it 1183b3ed458cSFrank Praznik * and keep flashing all of the LEDs until the PS button is pressed. 1184b3ed458cSFrank Praznik * Updates, even if redundant, must be always be sent to the 1185b3ed458cSFrank Praznik * controller to avoid having to toggle the state of an LED just to 1186b3ed458cSFrank Praznik * stop the flashing later on. 1187b3ed458cSFrank Praznik */ 1188b3ed458cSFrank Praznik force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB); 1189b3ed458cSFrank Praznik 119060781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1191b3ed458cSFrank Praznik if (led == drv_data->leds[n] && (force_update || 1192b3ed458cSFrank Praznik (value != drv_data->led_state[n] || 1193b3ed458cSFrank Praznik drv_data->led_delay_on[n] || 1194b3ed458cSFrank Praznik drv_data->led_delay_off[n]))) { 1195b3ed458cSFrank Praznik 119660781cf4SFrank Praznik drv_data->led_state[n] = value; 1197b3ed458cSFrank Praznik 1198b3ed458cSFrank Praznik /* Setting the brightness stops the blinking */ 1199b3ed458cSFrank Praznik drv_data->led_delay_on[n] = 0; 1200b3ed458cSFrank Praznik drv_data->led_delay_off[n] = 0; 1201b3ed458cSFrank Praznik 1202fa57a810SFrank Praznik sony_set_leds(drv_data, drv_data->led_state, 1203fa57a810SFrank Praznik drv_data->led_count); 1204f04d5140SColin Leitner break; 1205f04d5140SColin Leitner } 1206f04d5140SColin Leitner } 1207f04d5140SColin Leitner } 1208f04d5140SColin Leitner 1209c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1210f04d5140SColin Leitner { 1211f04d5140SColin Leitner struct device *dev = led->dev->parent; 1212f04d5140SColin Leitner struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1213f04d5140SColin Leitner struct sony_sc *drv_data; 1214f04d5140SColin Leitner 1215f04d5140SColin Leitner int n; 1216f04d5140SColin Leitner 1217f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 12182251b85fSSven Eckelmann if (!drv_data) { 1219f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1220f04d5140SColin Leitner return LED_OFF; 1221f04d5140SColin Leitner } 1222f04d5140SColin Leitner 122360781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 12247db7504aSSimon Wood if (led == drv_data->leds[n]) 12257db7504aSSimon Wood return drv_data->led_state[n]; 1226f04d5140SColin Leitner } 1227f04d5140SColin Leitner 12287db7504aSSimon Wood return LED_OFF; 1229f04d5140SColin Leitner } 1230f04d5140SColin Leitner 1231b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, 1232b3ed458cSFrank Praznik unsigned long *delay_off) 1233b3ed458cSFrank Praznik { 1234b3ed458cSFrank Praznik struct device *dev = led->dev->parent; 1235b3ed458cSFrank Praznik struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1236b3ed458cSFrank Praznik struct sony_sc *drv_data = hid_get_drvdata(hdev); 1237b3ed458cSFrank Praznik int n; 1238b3ed458cSFrank Praznik __u8 new_on, new_off; 1239b3ed458cSFrank Praznik 1240b3ed458cSFrank Praznik if (!drv_data) { 1241b3ed458cSFrank Praznik hid_err(hdev, "No device data\n"); 1242b3ed458cSFrank Praznik return -EINVAL; 1243b3ed458cSFrank Praznik } 1244b3ed458cSFrank Praznik 1245b3ed458cSFrank Praznik /* Max delay is 255 deciseconds or 2550 milliseconds */ 1246b3ed458cSFrank Praznik if (*delay_on > 2550) 1247b3ed458cSFrank Praznik *delay_on = 2550; 1248b3ed458cSFrank Praznik if (*delay_off > 2550) 1249b3ed458cSFrank Praznik *delay_off = 2550; 1250b3ed458cSFrank Praznik 1251b3ed458cSFrank Praznik /* Blink at 1 Hz if both values are zero */ 1252b3ed458cSFrank Praznik if (!*delay_on && !*delay_off) 1253b3ed458cSFrank Praznik *delay_on = *delay_off = 500; 1254b3ed458cSFrank Praznik 1255b3ed458cSFrank Praznik new_on = *delay_on / 10; 1256b3ed458cSFrank Praznik new_off = *delay_off / 10; 1257b3ed458cSFrank Praznik 1258b3ed458cSFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1259b3ed458cSFrank Praznik if (led == drv_data->leds[n]) 1260b3ed458cSFrank Praznik break; 1261b3ed458cSFrank Praznik } 1262b3ed458cSFrank Praznik 1263b3ed458cSFrank Praznik /* This LED is not registered on this device */ 1264b3ed458cSFrank Praznik if (n >= drv_data->led_count) 1265b3ed458cSFrank Praznik return -EINVAL; 1266b3ed458cSFrank Praznik 1267b3ed458cSFrank Praznik /* Don't schedule work if the values didn't change */ 1268b3ed458cSFrank Praznik if (new_on != drv_data->led_delay_on[n] || 1269b3ed458cSFrank Praznik new_off != drv_data->led_delay_off[n]) { 1270b3ed458cSFrank Praznik drv_data->led_delay_on[n] = new_on; 1271b3ed458cSFrank Praznik drv_data->led_delay_off[n] = new_off; 1272b3ed458cSFrank Praznik schedule_work(&drv_data->state_worker); 1273b3ed458cSFrank Praznik } 1274b3ed458cSFrank Praznik 1275b3ed458cSFrank Praznik return 0; 1276b3ed458cSFrank Praznik } 1277b3ed458cSFrank Praznik 1278fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc) 12790a286ef2SSven Eckelmann { 12800a286ef2SSven Eckelmann struct led_classdev *led; 12810a286ef2SSven Eckelmann int n; 12820a286ef2SSven Eckelmann 1283fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 12840a286ef2SSven Eckelmann 1285fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 1286fa57a810SFrank Praznik led = sc->leds[n]; 1287fa57a810SFrank Praznik sc->leds[n] = NULL; 12880a286ef2SSven Eckelmann if (!led) 12890a286ef2SSven Eckelmann continue; 12900a286ef2SSven Eckelmann led_classdev_unregister(led); 12910a286ef2SSven Eckelmann kfree(led); 12920a286ef2SSven Eckelmann } 129360781cf4SFrank Praznik 1294fa57a810SFrank Praznik sc->led_count = 0; 12950a286ef2SSven Eckelmann } 12960a286ef2SSven Eckelmann 1297fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc) 1298f04d5140SColin Leitner { 1299fa57a810SFrank Praznik struct hid_device *hdev = sc->hdev; 130040e32ee6SJiri Kosina int n, ret = 0; 1301b3ed458cSFrank Praznik int use_ds4_names; 130240e32ee6SJiri Kosina struct led_classdev *led; 130340e32ee6SJiri Kosina size_t name_sz; 130440e32ee6SJiri Kosina char *name; 13050a286ef2SSven Eckelmann size_t name_len; 13060a286ef2SSven Eckelmann const char *name_fmt; 1307b3ed458cSFrank Praznik static const char * const ds4_name_str[] = { "red", "green", "blue", 1308b3ed458cSFrank Praznik "global" }; 13098025087aSFrank Praznik __u8 initial_values[MAX_LEDS] = { 0 }; 1310b3ed458cSFrank Praznik __u8 max_brightness[MAX_LEDS] = { 1 }; 1311b3ed458cSFrank Praznik __u8 use_hw_blink[MAX_LEDS] = { 0 }; 1312f04d5140SColin Leitner 1313fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1314f04d5140SColin Leitner 1315fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER) { 1316fa57a810SFrank Praznik sc->led_count = 4; 1317b3ed458cSFrank Praznik use_ds4_names = 0; 13180a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 13190a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 13209446edb9SKees Cook /* Validate expected report characteristics. */ 13219446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 13229446edb9SKees Cook return -ENODEV; 1323fa57a810SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 13248025087aSFrank Praznik dualshock4_set_leds_from_id(sc->device_id, initial_values); 1325b3ed458cSFrank Praznik initial_values[3] = 1; 1326b3ed458cSFrank Praznik sc->led_count = 4; 1327b3ed458cSFrank Praznik memset(max_brightness, 255, 3); 1328b3ed458cSFrank Praznik use_hw_blink[3] = 1; 1329b3ed458cSFrank Praznik use_ds4_names = 1; 133061ebca93SFrank Praznik name_len = 0; 133161ebca93SFrank Praznik name_fmt = "%s:%s"; 133260781cf4SFrank Praznik } else { 13338025087aSFrank Praznik sixaxis_set_leds_from_id(sc->device_id, initial_values); 1334fa57a810SFrank Praznik sc->led_count = 4; 1335b3ed458cSFrank Praznik memset(use_hw_blink, 1, 4); 1336b3ed458cSFrank Praznik use_ds4_names = 0; 133761ebca93SFrank Praznik name_len = strlen("::sony#"); 133861ebca93SFrank Praznik name_fmt = "%s::sony%d"; 133960781cf4SFrank Praznik } 134060781cf4SFrank Praznik 1341ad142b9eSFrank Praznik /* 1342ad142b9eSFrank Praznik * Clear LEDs as we have no way of reading their initial state. This is 1343f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1344ad142b9eSFrank Praznik * LEDs to on 1345ad142b9eSFrank Praznik */ 1346fa57a810SFrank Praznik sony_set_leds(sc, initial_values, sc->led_count); 1347f04d5140SColin Leitner 13480a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1349f04d5140SColin Leitner 1350fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 135161ebca93SFrank Praznik 1352b3ed458cSFrank Praznik if (use_ds4_names) 1353b3ed458cSFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2; 135461ebca93SFrank Praznik 1355f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1356f04d5140SColin Leitner if (!led) { 1357f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 13588cd5fcdaSJulia Lawall ret = -ENOMEM; 1359f04d5140SColin Leitner goto error_leds; 1360f04d5140SColin Leitner } 1361f04d5140SColin Leitner 1362f04d5140SColin Leitner name = (void *)(&led[1]); 1363b3ed458cSFrank Praznik if (use_ds4_names) 1364b3ed458cSFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), 1365b3ed458cSFrank Praznik ds4_name_str[n]); 136661ebca93SFrank Praznik else 13670a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1368f04d5140SColin Leitner led->name = name; 13698025087aSFrank Praznik led->brightness = initial_values[n]; 1370b3ed458cSFrank Praznik led->max_brightness = max_brightness[n]; 1371c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1372c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1373f04d5140SColin Leitner 1374b3ed458cSFrank Praznik if (use_hw_blink[n]) 1375b3ed458cSFrank Praznik led->blink_set = sony_led_blink_set; 1376b3ed458cSFrank Praznik 13778025087aSFrank Praznik sc->leds[n] = led; 13788025087aSFrank Praznik 13798cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 13808cd5fcdaSJulia Lawall if (ret) { 1381f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 13828025087aSFrank Praznik sc->leds[n] = NULL; 1383f04d5140SColin Leitner kfree(led); 1384f04d5140SColin Leitner goto error_leds; 1385f04d5140SColin Leitner } 1386f04d5140SColin Leitner } 1387f04d5140SColin Leitner 1388f04d5140SColin Leitner return ret; 1389f04d5140SColin Leitner 1390f04d5140SColin Leitner error_leds: 1391fa57a810SFrank Praznik sony_leds_remove(sc); 1392f04d5140SColin Leitner 1393f04d5140SColin Leitner return ret; 1394f04d5140SColin Leitner } 1395f04d5140SColin Leitner 1396cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work) 1397a08c22c0SSven Eckelmann { 139892b5c411SSven Eckelmann struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 1399b3ed458cSFrank Praznik int n; 140055d3b664SFrank Praznik union sixaxis_output_report_01 report = { 140155d3b664SFrank Praznik .buf = { 1402a08c22c0SSven Eckelmann 0x01, 1403a08c22c0SSven Eckelmann 0x00, 0xff, 0x00, 0xff, 0x00, 14040a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1405a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1406a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1407a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1408a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1409a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 141055d3b664SFrank Praznik } 1411a08c22c0SSven Eckelmann }; 14129f323b68SSven Eckelmann 14130a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 141455d3b664SFrank Praznik report.data.rumble.right_motor_on = sc->right ? 1 : 0; 141555d3b664SFrank Praznik report.data.rumble.left_motor_force = sc->left; 14160a286ef2SSven Eckelmann #endif 14170a286ef2SSven Eckelmann 141855d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[0] << 1; 141955d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[1] << 2; 142055d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[2] << 3; 142155d3b664SFrank Praznik report.data.leds_bitmap |= sc->led_state[3] << 4; 14229f323b68SSven Eckelmann 142388f6576fSSimon Wood /* Set flag for all leds off, required for 3rd party INTEC controller */ 142488f6576fSSimon Wood if ((report.data.leds_bitmap & 0x1E) == 0) 142588f6576fSSimon Wood report.data.leds_bitmap |= 0x20; 142688f6576fSSimon Wood 1427b3ed458cSFrank Praznik /* 1428b3ed458cSFrank Praznik * The LEDs in the report are indexed in reverse order to their 1429b3ed458cSFrank Praznik * corresponding light on the controller. 1430b3ed458cSFrank Praznik * Index 0 = LED 4, index 1 = LED 3, etc... 1431b3ed458cSFrank Praznik * 1432b3ed458cSFrank Praznik * In the case of both delay values being zero (blinking disabled) the 1433b3ed458cSFrank Praznik * default report values should be used or the controller LED will be 1434b3ed458cSFrank Praznik * always off. 1435b3ed458cSFrank Praznik */ 1436b3ed458cSFrank Praznik for (n = 0; n < 4; n++) { 1437b3ed458cSFrank Praznik if (sc->led_delay_on[n] || sc->led_delay_off[n]) { 1438b3ed458cSFrank Praznik report.data.led[3 - n].duty_off = sc->led_delay_off[n]; 1439b3ed458cSFrank Praznik report.data.led[3 - n].duty_on = sc->led_delay_on[n]; 1440b3ed458cSFrank Praznik } 1441b3ed458cSFrank Praznik } 1442b3ed458cSFrank Praznik 144355d3b664SFrank Praznik hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf, 144455d3b664SFrank Praznik sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 14459f323b68SSven Eckelmann } 14469f323b68SSven Eckelmann 14470bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work) 14480bd88dd3SFrank Praznik { 14490bd88dd3SFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 14500da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 145148220237SFrank Praznik int offset; 14520da8ea65SFrank Praznik 1453fdcf105dSFrank Praznik __u8 buf[78] = { 0 }; 145448220237SFrank Praznik 1455fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 145648220237SFrank Praznik buf[0] = 0x05; 1457b3ed458cSFrank Praznik buf[1] = 0xFF; 145848220237SFrank Praznik offset = 4; 1459fdcf105dSFrank Praznik } else { 1460fdcf105dSFrank Praznik buf[0] = 0x11; 1461fdcf105dSFrank Praznik buf[1] = 0xB0; 1462fdcf105dSFrank Praznik buf[3] = 0x0F; 1463fdcf105dSFrank Praznik offset = 6; 1464fdcf105dSFrank Praznik } 14650bd88dd3SFrank Praznik 14660bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 146748220237SFrank Praznik buf[offset++] = sc->right; 146848220237SFrank Praznik buf[offset++] = sc->left; 146948220237SFrank Praznik #else 147048220237SFrank Praznik offset += 2; 14710bd88dd3SFrank Praznik #endif 14720bd88dd3SFrank Praznik 1473b3ed458cSFrank Praznik /* LED 3 is the global control */ 1474b3ed458cSFrank Praznik if (sc->led_state[3]) { 147548220237SFrank Praznik buf[offset++] = sc->led_state[0]; 147648220237SFrank Praznik buf[offset++] = sc->led_state[1]; 147748220237SFrank Praznik buf[offset++] = sc->led_state[2]; 1478b3ed458cSFrank Praznik } else { 1479b3ed458cSFrank Praznik offset += 3; 1480b3ed458cSFrank Praznik } 1481b3ed458cSFrank Praznik 1482b3ed458cSFrank Praznik /* If both delay values are zero the DualShock 4 disables blinking. */ 1483b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_on[3]; 1484b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_off[3]; 148560781cf4SFrank Praznik 1486fdcf105dSFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1487fdcf105dSFrank Praznik hid_hw_output_report(hdev, buf, 32); 1488fdcf105dSFrank Praznik else 1489fdcf105dSFrank Praznik hid_hw_raw_request(hdev, 0x11, buf, 78, 1490fdcf105dSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 14910bd88dd3SFrank Praznik } 14920bd88dd3SFrank Praznik 14930a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 14949f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 14959f323b68SSven Eckelmann struct ff_effect *effect) 14969f323b68SSven Eckelmann { 1497a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 14989f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 1499a08c22c0SSven Eckelmann 1500a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 1501a08c22c0SSven Eckelmann return 0; 1502a08c22c0SSven Eckelmann 15039f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 15040bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 1505a08c22c0SSven Eckelmann 150692b5c411SSven Eckelmann schedule_work(&sc->state_worker); 15079f323b68SSven Eckelmann return 0; 1508a08c22c0SSven Eckelmann } 1509a08c22c0SSven Eckelmann 1510fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1511a08c22c0SSven Eckelmann { 1512fa57a810SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1513a08c22c0SSven Eckelmann struct hid_input, list); 1514a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 1515a08c22c0SSven Eckelmann 1516a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 1517a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 1518a08c22c0SSven Eckelmann } 1519a08c22c0SSven Eckelmann 1520a08c22c0SSven Eckelmann #else 1521fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 1522a08c22c0SSven Eckelmann { 1523a08c22c0SSven Eckelmann return 0; 1524a08c22c0SSven Eckelmann } 15259f323b68SSven Eckelmann 1526a08c22c0SSven Eckelmann #endif 1527a08c22c0SSven Eckelmann 1528d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 1529d902f472SFrank Praznik enum power_supply_property psp, 1530d902f472SFrank Praznik union power_supply_propval *val) 1531c4e1ddf2SFrank Praznik { 1532d902f472SFrank Praznik struct sony_sc *sc = container_of(psy, struct sony_sc, battery); 1533d902f472SFrank Praznik unsigned long flags; 1534d902f472SFrank Praznik int ret = 0; 1535d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 1536c4e1ddf2SFrank Praznik 1537d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 1538d902f472SFrank Praznik battery_charging = sc->battery_charging; 1539d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 1540d902f472SFrank Praznik cable_state = sc->cable_state; 1541d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 1542c4e1ddf2SFrank Praznik 1543d902f472SFrank Praznik switch (psp) { 1544d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 1545d902f472SFrank Praznik val->intval = 1; 1546d902f472SFrank Praznik break; 1547d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 1548d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 1549d902f472SFrank Praznik break; 1550d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 1551d902f472SFrank Praznik val->intval = battery_capacity; 1552d902f472SFrank Praznik break; 1553d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 1554d902f472SFrank Praznik if (battery_charging) 1555d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 1556d902f472SFrank Praznik else 1557d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 1558d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 1559d902f472SFrank Praznik else 1560d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1561d902f472SFrank Praznik break; 1562d902f472SFrank Praznik default: 1563d902f472SFrank Praznik ret = -EINVAL; 1564d902f472SFrank Praznik break; 1565c4e1ddf2SFrank Praznik } 1566d902f472SFrank Praznik return ret; 1567d902f472SFrank Praznik } 1568d902f472SFrank Praznik 1569d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc) 1570d902f472SFrank Praznik { 1571d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 1572d902f472SFrank Praznik int ret; 1573d902f472SFrank Praznik 1574ad142b9eSFrank Praznik /* 1575ad142b9eSFrank Praznik * Set the default battery level to 100% to avoid low battery warnings 1576d9a293a9SFrank Praznik * if the battery is polled before the first device report is received. 1577d9a293a9SFrank Praznik */ 1578d9a293a9SFrank Praznik sc->battery_capacity = 100; 1579d9a293a9SFrank Praznik 1580d902f472SFrank Praznik sc->battery.properties = sony_battery_props; 1581d902f472SFrank Praznik sc->battery.num_properties = ARRAY_SIZE(sony_battery_props); 1582d902f472SFrank Praznik sc->battery.get_property = sony_battery_get_property; 1583d902f472SFrank Praznik sc->battery.type = POWER_SUPPLY_TYPE_BATTERY; 1584d902f472SFrank Praznik sc->battery.use_for_apm = 0; 1585314531f1SFrank Praznik sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR", 1586314531f1SFrank Praznik sc->mac_address); 1587d902f472SFrank Praznik if (!sc->battery.name) 1588d902f472SFrank Praznik return -ENOMEM; 1589d902f472SFrank Praznik 1590d902f472SFrank Praznik ret = power_supply_register(&hdev->dev, &sc->battery); 1591d902f472SFrank Praznik if (ret) { 1592d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 1593d902f472SFrank Praznik goto err_free; 1594d902f472SFrank Praznik } 1595d902f472SFrank Praznik 1596d902f472SFrank Praznik power_supply_powers(&sc->battery, &hdev->dev); 1597d902f472SFrank Praznik return 0; 1598d902f472SFrank Praznik 1599d902f472SFrank Praznik err_free: 1600d902f472SFrank Praznik kfree(sc->battery.name); 1601d902f472SFrank Praznik sc->battery.name = NULL; 1602d902f472SFrank Praznik return ret; 1603d902f472SFrank Praznik } 1604d902f472SFrank Praznik 1605d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 1606d902f472SFrank Praznik { 1607d902f472SFrank Praznik if (!sc->battery.name) 1608d902f472SFrank Praznik return; 1609d902f472SFrank Praznik 1610d902f472SFrank Praznik power_supply_unregister(&sc->battery); 1611d902f472SFrank Praznik kfree(sc->battery.name); 1612d902f472SFrank Praznik sc->battery.name = NULL; 1613d902f472SFrank Praznik } 1614d902f472SFrank Praznik 1615e5606230SFrank Praznik static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1616e5606230SFrank Praznik int w, int h) 1617e5606230SFrank Praznik { 1618e5606230SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 1619e5606230SFrank Praznik struct hid_input, list); 1620e5606230SFrank Praznik struct input_dev *input_dev = hidinput->input; 1621e5606230SFrank Praznik int ret; 1622e5606230SFrank Praznik 1623e5606230SFrank Praznik ret = input_mt_init_slots(input_dev, touch_count, 0); 1624e5606230SFrank Praznik if (ret < 0) { 1625e5606230SFrank Praznik hid_err(sc->hdev, "Unable to initialize multi-touch slots\n"); 1626e5606230SFrank Praznik return ret; 1627e5606230SFrank Praznik } 1628e5606230SFrank Praznik 1629e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0); 1630e5606230SFrank Praznik input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0); 1631e5606230SFrank Praznik 1632c4e1ddf2SFrank Praznik return 0; 1633c4e1ddf2SFrank Praznik } 1634e5606230SFrank Praznik 1635d2d782fcSFrank Praznik /* 1636d2d782fcSFrank Praznik * If a controller is plugged in via USB while already connected via Bluetooth 1637d2d782fcSFrank Praznik * it will show up as two devices. A global list of connected controllers and 1638d2d782fcSFrank Praznik * their MAC addresses is maintained to ensure that a device is only connected 1639d2d782fcSFrank Praznik * once. 1640d2d782fcSFrank Praznik */ 1641d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc) 1642d2d782fcSFrank Praznik { 1643d2d782fcSFrank Praznik struct sony_sc *entry; 1644d2d782fcSFrank Praznik unsigned long flags; 1645d2d782fcSFrank Praznik int ret; 1646d2d782fcSFrank Praznik 1647d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1648d2d782fcSFrank Praznik 1649d2d782fcSFrank Praznik list_for_each_entry(entry, &sony_device_list, list_node) { 1650d2d782fcSFrank Praznik ret = memcmp(sc->mac_address, entry->mac_address, 1651d2d782fcSFrank Praznik sizeof(sc->mac_address)); 1652d2d782fcSFrank Praznik if (!ret) { 1653d2d782fcSFrank Praznik ret = -EEXIST; 1654d2d782fcSFrank Praznik hid_info(sc->hdev, "controller with MAC address %pMR already connected\n", 1655d2d782fcSFrank Praznik sc->mac_address); 1656d2d782fcSFrank Praznik goto unlock; 1657d2d782fcSFrank Praznik } 1658c4e1ddf2SFrank Praznik } 1659c4e1ddf2SFrank Praznik 1660d2d782fcSFrank Praznik ret = 0; 1661d2d782fcSFrank Praznik list_add(&(sc->list_node), &sony_device_list); 1662c4e1ddf2SFrank Praznik 1663d2d782fcSFrank Praznik unlock: 1664d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1665d2d782fcSFrank Praznik return ret; 1666d2d782fcSFrank Praznik } 1667d2d782fcSFrank Praznik 1668d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc) 1669d2d782fcSFrank Praznik { 1670d2d782fcSFrank Praznik unsigned long flags; 1671d2d782fcSFrank Praznik 1672d2d782fcSFrank Praznik if (sc->list_node.next) { 1673d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 1674d2d782fcSFrank Praznik list_del(&(sc->list_node)); 1675d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 1676d2d782fcSFrank Praznik } 1677d2d782fcSFrank Praznik } 1678d2d782fcSFrank Praznik 1679d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc) 1680d2d782fcSFrank Praznik { 1681d2d782fcSFrank Praznik int ret; 1682d2d782fcSFrank Praznik 1683d2d782fcSFrank Praznik /* HIDP stores the device MAC address as a string in the uniq field. */ 1684d2d782fcSFrank Praznik ret = strlen(sc->hdev->uniq); 1685d2d782fcSFrank Praznik if (ret != 17) 1686c4e1ddf2SFrank Praznik return -EINVAL; 1687d2d782fcSFrank Praznik 1688d2d782fcSFrank Praznik ret = sscanf(sc->hdev->uniq, 1689d2d782fcSFrank Praznik "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 1690d2d782fcSFrank Praznik &sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3], 1691d2d782fcSFrank Praznik &sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]); 1692d2d782fcSFrank Praznik 1693d2d782fcSFrank Praznik if (ret != 6) 1694d2d782fcSFrank Praznik return -EINVAL; 1695d2d782fcSFrank Praznik 1696d2d782fcSFrank Praznik return 0; 1697c4e1ddf2SFrank Praznik } 1698c4e1ddf2SFrank Praznik 1699d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc) 1700d2d782fcSFrank Praznik { 1701d2d782fcSFrank Praznik int n, ret; 1702d2d782fcSFrank Praznik 1703d2d782fcSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || 1704d2d782fcSFrank Praznik (sc->quirks & SIXAXIS_CONTROLLER_BT)) { 1705d2d782fcSFrank Praznik /* 1706d2d782fcSFrank Praznik * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC 1707d2d782fcSFrank Praznik * address from the uniq string where HIDP stores it. 1708d2d782fcSFrank Praznik * As uniq cannot be guaranteed to be a MAC address in all cases 1709d2d782fcSFrank Praznik * a failure of this function should not prevent the connection. 1710d2d782fcSFrank Praznik */ 1711d2d782fcSFrank Praznik if (sony_get_bt_devaddr(sc) < 0) { 1712d2d782fcSFrank Praznik hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); 1713d2d782fcSFrank Praznik return 0; 1714d2d782fcSFrank Praznik } 1715d2d782fcSFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 1716d2d782fcSFrank Praznik __u8 buf[7]; 1717d2d782fcSFrank Praznik 1718d2d782fcSFrank Praznik /* 1719d2d782fcSFrank Praznik * The MAC address of a DS4 controller connected via USB can be 1720d2d782fcSFrank Praznik * retrieved with feature report 0x81. The address begins at 1721d2d782fcSFrank Praznik * offset 1. 1722d2d782fcSFrank Praznik */ 1723d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf), 1724d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1725d2d782fcSFrank Praznik 1726d2d782fcSFrank Praznik if (ret != 7) { 1727d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); 1728d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1729d2d782fcSFrank Praznik } 1730d2d782fcSFrank Praznik 1731d2d782fcSFrank Praznik memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); 1732d2d782fcSFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1733d2d782fcSFrank Praznik __u8 buf[18]; 1734d2d782fcSFrank Praznik 1735d2d782fcSFrank Praznik /* 1736d2d782fcSFrank Praznik * The MAC address of a Sixaxis controller connected via USB can 1737d2d782fcSFrank Praznik * be retrieved with feature report 0xf2. The address begins at 1738d2d782fcSFrank Praznik * offset 4. 1739d2d782fcSFrank Praznik */ 1740d2d782fcSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf), 1741d2d782fcSFrank Praznik HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1742d2d782fcSFrank Praznik 1743d2d782fcSFrank Praznik if (ret != 18) { 1744d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); 1745d2d782fcSFrank Praznik return ret < 0 ? ret : -EINVAL; 1746d2d782fcSFrank Praznik } 1747d2d782fcSFrank Praznik 1748d2d782fcSFrank Praznik /* 1749d2d782fcSFrank Praznik * The Sixaxis device MAC in the report is big-endian and must 1750d2d782fcSFrank Praznik * be byte-swapped. 1751d2d782fcSFrank Praznik */ 1752d2d782fcSFrank Praznik for (n = 0; n < 6; n++) 1753d2d782fcSFrank Praznik sc->mac_address[5-n] = buf[4+n]; 1754d2d782fcSFrank Praznik } else { 1755d2d782fcSFrank Praznik return 0; 1756d2d782fcSFrank Praznik } 1757d2d782fcSFrank Praznik 1758d2d782fcSFrank Praznik return sony_check_add_dev_list(sc); 1759d2d782fcSFrank Praznik } 1760d2d782fcSFrank Praznik 17618025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc) 17628025087aSFrank Praznik { 17638025087aSFrank Praznik int ret; 17648025087aSFrank Praznik 17658025087aSFrank Praznik /* 17668025087aSFrank Praznik * Only DualShock 4 or Sixaxis controllers get an id. 17678025087aSFrank Praznik * All others are set to -1. 17688025087aSFrank Praznik */ 17698025087aSFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) || 17708025087aSFrank Praznik (sc->quirks & DUALSHOCK4_CONTROLLER)) { 17718025087aSFrank Praznik ret = ida_simple_get(&sony_device_id_allocator, 0, 0, 17728025087aSFrank Praznik GFP_KERNEL); 17738025087aSFrank Praznik if (ret < 0) { 17748025087aSFrank Praznik sc->device_id = -1; 17758025087aSFrank Praznik return ret; 17768025087aSFrank Praznik } 17778025087aSFrank Praznik sc->device_id = ret; 17788025087aSFrank Praznik } else { 17798025087aSFrank Praznik sc->device_id = -1; 17808025087aSFrank Praznik } 17818025087aSFrank Praznik 17828025087aSFrank Praznik return 0; 17838025087aSFrank Praznik } 17848025087aSFrank Praznik 17858025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc) 17868025087aSFrank Praznik { 17878025087aSFrank Praznik if (sc->device_id >= 0) { 17888025087aSFrank Praznik ida_simple_remove(&sony_device_id_allocator, sc->device_id); 17898025087aSFrank Praznik sc->device_id = -1; 17908025087aSFrank Praznik } 17918025087aSFrank Praznik } 17928025087aSFrank Praznik 179346262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc, 179446262047SFrank Praznik void (*worker)(struct work_struct *)) 179546262047SFrank Praznik { 179646262047SFrank Praznik if (!sc->worker_initialized) 179746262047SFrank Praznik INIT_WORK(&sc->state_worker, worker); 179846262047SFrank Praznik 179946262047SFrank Praznik sc->worker_initialized = 1; 180046262047SFrank Praznik } 180146262047SFrank Praznik 180246262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc) 180346262047SFrank Praznik { 180446262047SFrank Praznik if (sc->worker_initialized) 180546262047SFrank Praznik cancel_work_sync(&sc->state_worker); 180646262047SFrank Praznik } 1807d2d782fcSFrank Praznik 1808bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 1809bd28ce00SJiri Slaby { 1810bd28ce00SJiri Slaby int ret; 1811cc6e0bbbSJiri Kosina unsigned long quirks = id->driver_data; 1812cc6e0bbbSJiri Kosina struct sony_sc *sc; 1813f04d5140SColin Leitner unsigned int connect_mask = HID_CONNECT_DEFAULT; 1814cc6e0bbbSJiri Kosina 1815abf832bfSBenjamin Tissoires sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 1816cc6e0bbbSJiri Kosina if (sc == NULL) { 18174291ee30SJoe Perches hid_err(hdev, "can't alloc sony descriptor\n"); 1818cc6e0bbbSJiri Kosina return -ENOMEM; 1819cc6e0bbbSJiri Kosina } 1820cc6e0bbbSJiri Kosina 1821cc6e0bbbSJiri Kosina sc->quirks = quirks; 1822cc6e0bbbSJiri Kosina hid_set_drvdata(hdev, sc); 18230a286ef2SSven Eckelmann sc->hdev = hdev; 1824bd28ce00SJiri Slaby 1825bd28ce00SJiri Slaby ret = hid_parse(hdev); 1826bd28ce00SJiri Slaby if (ret) { 18274291ee30SJoe Perches hid_err(hdev, "parse failed\n"); 1828abf832bfSBenjamin Tissoires return ret; 1829bd28ce00SJiri Slaby } 1830bd28ce00SJiri Slaby 1831f04d5140SColin Leitner if (sc->quirks & VAIO_RDESC_CONSTANT) 1832f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1833*50764650SAntonio Ospite else if (sc->quirks & SIXAXIS_CONTROLLER) 1834f04d5140SColin Leitner connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1835f04d5140SColin Leitner 1836f04d5140SColin Leitner ret = hid_hw_start(hdev, connect_mask); 1837bd28ce00SJiri Slaby if (ret) { 18384291ee30SJoe Perches hid_err(hdev, "hw start failed\n"); 1839abf832bfSBenjamin Tissoires return ret; 1840bd28ce00SJiri Slaby } 1841bd28ce00SJiri Slaby 18428025087aSFrank Praznik ret = sony_set_device_id(sc); 18438025087aSFrank Praznik if (ret < 0) { 18448025087aSFrank Praznik hid_err(hdev, "failed to allocate the device id\n"); 18458025087aSFrank Praznik goto err_stop; 18468025087aSFrank Praznik } 18478025087aSFrank Praznik 1848569b10a5SAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 1849e534a935SBenjamin Tissoires /* 1850e534a935SBenjamin Tissoires * The Sony Sixaxis does not handle HID Output Reports on the 1851e534a935SBenjamin Tissoires * Interrupt EP like it could, so we need to force HID Output 1852e534a935SBenjamin Tissoires * Reports to use HID_REQ_SET_REPORT on the Control EP. 1853e534a935SBenjamin Tissoires * 1854e534a935SBenjamin Tissoires * There is also another issue about HID Output Reports via USB, 1855e534a935SBenjamin Tissoires * the Sixaxis does not want the report_id as part of the data 1856e534a935SBenjamin Tissoires * packet, so we have to discard buf[0] when sending the actual 1857e534a935SBenjamin Tissoires * control message, even for numbered reports, humpf! 1858e534a935SBenjamin Tissoires */ 1859e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1860e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; 1861816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 186246262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1863fee4e2d5SFrank Praznik } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) { 18642078b9bbSFrank Praznik /* 18652078b9bbSFrank Praznik * The Sixaxis wants output reports sent on the ctrl endpoint 18662078b9bbSFrank Praznik * when connected via Bluetooth. 18672078b9bbSFrank Praznik */ 18682078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 1869816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 187046262047SFrank Praznik sony_init_work(sc, sixaxis_state_worker); 1871fee4e2d5SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 187268330d83SFrank Praznik if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { 18732078b9bbSFrank Praznik /* 18742078b9bbSFrank Praznik * The DualShock 4 wants output reports sent on the ctrl 18752078b9bbSFrank Praznik * endpoint when connected via Bluetooth. 18762078b9bbSFrank Praznik */ 18772078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 187868330d83SFrank Praznik ret = dualshock4_set_operational_bt(hdev); 187968330d83SFrank Praznik if (ret < 0) { 188068330d83SFrank Praznik hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); 188168330d83SFrank Praznik goto err_stop; 188268330d83SFrank Praznik } 188368330d83SFrank Praznik } 1884ad142b9eSFrank Praznik /* 1885ad142b9eSFrank Praznik * The Dualshock 4 touchpad supports 2 touches and has a 1886e5606230SFrank Praznik * resolution of 1920x940. 1887e5606230SFrank Praznik */ 1888e5606230SFrank Praznik ret = sony_register_touchpad(sc, 2, 1920, 940); 1889c4e1ddf2SFrank Praznik if (ret < 0) 1890c4e1ddf2SFrank Praznik goto err_stop; 1891c4e1ddf2SFrank Praznik 189246262047SFrank Praznik sony_init_work(sc, dualshock4_state_worker); 18930bd88dd3SFrank Praznik } else { 18940bd88dd3SFrank Praznik ret = 0; 18950bd88dd3SFrank Praznik } 1896f9ce7c28SBastien Nocera 18974dfdc464SJiri Kosina if (ret < 0) 1898bd28ce00SJiri Slaby goto err_stop; 1899bd28ce00SJiri Slaby 1900d2d782fcSFrank Praznik ret = sony_check_add(sc); 1901d2d782fcSFrank Praznik if (ret < 0) 1902d2d782fcSFrank Praznik goto err_stop; 1903d2d782fcSFrank Praznik 19040a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 1905fa57a810SFrank Praznik ret = sony_leds_init(sc); 19060a286ef2SSven Eckelmann if (ret < 0) 19070a286ef2SSven Eckelmann goto err_stop; 19080a286ef2SSven Eckelmann } 19090a286ef2SSven Eckelmann 1910d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1911d902f472SFrank Praznik ret = sony_battery_probe(sc); 1912a08c22c0SSven Eckelmann if (ret < 0) 1913a08c22c0SSven Eckelmann goto err_stop; 1914a08c22c0SSven Eckelmann 1915d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 1916d902f472SFrank Praznik ret = hid_hw_open(hdev); 1917d902f472SFrank Praznik if (ret < 0) { 1918d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 1919d902f472SFrank Praznik goto err_stop; 1920d902f472SFrank Praznik } 1921d902f472SFrank Praznik } 1922d902f472SFrank Praznik 1923c8de9dbbSFrank Praznik if (sc->quirks & SONY_FF_SUPPORT) { 1924fa57a810SFrank Praznik ret = sony_init_ff(sc); 1925d902f472SFrank Praznik if (ret < 0) 1926d902f472SFrank Praznik goto err_close; 19275f5750d2SFrank Praznik } 1928bd28ce00SJiri Slaby 1929f425458eSH Hartley Sweeten return 0; 1930d902f472SFrank Praznik err_close: 1931d902f472SFrank Praznik hid_hw_close(hdev); 1932bd28ce00SJiri Slaby err_stop: 19330a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1934fa57a810SFrank Praznik sony_leds_remove(sc); 1935d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 1936d902f472SFrank Praznik sony_battery_remove(sc); 193746262047SFrank Praznik sony_cancel_work_sync(sc); 1938d2d782fcSFrank Praznik sony_remove_dev_list(sc); 19398025087aSFrank Praznik sony_release_device_id(sc); 1940bd28ce00SJiri Slaby hid_hw_stop(hdev); 1941bd28ce00SJiri Slaby return ret; 1942bd28ce00SJiri Slaby } 1943bd28ce00SJiri Slaby 1944bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev) 1945bd28ce00SJiri Slaby { 1946bd28ce00SJiri Slaby struct sony_sc *sc = hid_get_drvdata(hdev); 1947bd28ce00SJiri Slaby 19480a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 1949fa57a810SFrank Praznik sony_leds_remove(sc); 1950bd28ce00SJiri Slaby 1951d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 1952d902f472SFrank Praznik hid_hw_close(hdev); 1953d902f472SFrank Praznik sony_battery_remove(sc); 1954d902f472SFrank Praznik } 1955d902f472SFrank Praznik 195646262047SFrank Praznik sony_cancel_work_sync(sc); 19579f323b68SSven Eckelmann 1958d2d782fcSFrank Praznik sony_remove_dev_list(sc); 1959bd28ce00SJiri Slaby 19608025087aSFrank Praznik sony_release_device_id(sc); 19618025087aSFrank Praznik 1962bd28ce00SJiri Slaby hid_hw_stop(hdev); 1963bd28ce00SJiri Slaby } 1964bd28ce00SJiri Slaby 1965bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 1966bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1967bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 1968bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 1969bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 1970bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 1971bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_BT }, 1972bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 1973bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 1974bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 1975bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 1976bd28ce00SJiri Slaby /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 1977bd28ce00SJiri Slaby * Logitech joystick from the device descriptor. */ 1978bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 1979bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 1980bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 1981bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 1982bd28ce00SJiri Slaby /* PS3 BD Remote Control */ 1983bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 1984bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 1985bd28ce00SJiri Slaby /* Logitech Harmony Adapter for PS3 */ 1986bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 1987bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 19880bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 19890bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 19908ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 19910bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 19928ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 1993bd28ce00SJiri Slaby { } 1994bd28ce00SJiri Slaby }; 1995bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 1996bd28ce00SJiri Slaby 1997bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 1998bd28ce00SJiri Slaby .name = "sony", 1999bd28ce00SJiri Slaby .id_table = sony_devices, 2000bd28ce00SJiri Slaby .input_mapping = sony_mapping, 2001bd28ce00SJiri Slaby .probe = sony_probe, 2002bd28ce00SJiri Slaby .remove = sony_remove, 2003bd28ce00SJiri Slaby .report_fixup = sony_report_fixup, 2004bd28ce00SJiri Slaby .raw_event = sony_raw_event 2005bd28ce00SJiri Slaby }; 20068025087aSFrank Praznik 20078025087aSFrank Praznik static int __init sony_init(void) 20088025087aSFrank Praznik { 20098025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20108025087aSFrank Praznik 20118025087aSFrank Praznik return hid_register_driver(&sony_driver); 20128025087aSFrank Praznik } 20138025087aSFrank Praznik 20148025087aSFrank Praznik static void __exit sony_exit(void) 20158025087aSFrank Praznik { 20168025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 20178025087aSFrank Praznik 20188025087aSFrank Praznik ida_destroy(&sony_device_id_allocator); 20198025087aSFrank Praznik hid_unregister_driver(&sony_driver); 20208025087aSFrank Praznik } 20218025087aSFrank Praznik module_init(sony_init); 20228025087aSFrank Praznik module_exit(sony_exit); 2023bd28ce00SJiri Slaby 2024bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 2025