···617617 Support for Samsung InfraRed remote control or keyboards.618618619619config HID_SONY620620- tristate "Sony PS2/3 accessories"620620+ tristate "Sony PS2/3/4 accessories"621621 depends on USB_HID622622 depends on NEW_LEDS623623 depends on LEDS_CLASS624624+ select POWER_SUPPLY624625 ---help---625626 Support for626627627628 * Sony PS3 6-axis controllers629629+ * Sony PS4 DualShock 4 controllers628630 * Buzz controllers629631 * Sony PS3 Blue-ray Disk Remote Control (Bluetooth)630632 * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)631633632634config SONY_FF633633- bool "Sony PS2/3 accessories force feedback support"635635+ bool "Sony PS2/3/4 accessories force feedback support" 634636 depends on HID_SONY635637 select INPUT_FF_MEMLESS636638 ---help---637637- Say Y here if you have a Sony PS2/3 accessory and want to enable force638638- feedback support for it.639639+ Say Y here if you have a Sony PS2/3/4 accessory and want to enable640640+ force feedback support for it.639641640642config HID_SPEEDLINK641643 tristate "Speedlink VAD Cezanne mouse support"
+694-64
drivers/hid/hid-sony.c
···1717 * any later version.1818 */19192020-/* NOTE: in order for the Sony PS3 BD Remote Control to be found by2020+/*2121+ * NOTE: in order for the Sony PS3 BD Remote Control to be found by2122 * a Bluetooth host, the key combination Start+Enter has to be kept pressed2223 * for about 7 seconds with the Bluetooth Host Controller in discovering mode.2324 *···3130#include <linux/slab.h>3231#include <linux/usb.h>3332#include <linux/leds.h>3333+#include <linux/power_supply.h>3434+#include <linux/spinlock.h>3535+#include <linux/list.h>3636+#include <linux/input/mt.h>34373538#include "hid-ids.h"3639···4641#define DUALSHOCK4_CONTROLLER_USB BIT(5)4742#define DUALSHOCK4_CONTROLLER_BT BIT(6)48434949-#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB)4444+#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)4545+#define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\4646+ DUALSHOCK4_CONTROLLER_BT)4747+#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\4848+ DUALSHOCK4_CONTROLLER)4949+#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)5050+#define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)50515152#define MAX_LEDS 45253···8473 0xb1, 0x02, 0xc0, 0xc0,8574};86758787-/* The default descriptor doesn't provide mapping for the accelerometers7676+/*7777+ * The default descriptor doesn't provide mapping for the accelerometers8878 * or orientation sensors. This fixed descriptor maps the accelerometers8979 * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors9080 * to usage values 0x43, 0x44 and 0x45.···344332 0xC0 /* End Collection */345333};346334335335+/*336336+ * The default behavior of the Dualshock 4 is to send reports using report337337+ * type 1 when running over Bluetooth. However, as soon as it receives a338338+ * report of type 17 to set the LEDs or rumble it starts returning it's state339339+ * in report 17 instead of 1. Since report 17 is undefined in the default HID340340+ * descriptor the button and axis definitions must be moved to report 17 or341341+ * the HID layer won't process the received input once a report is sent.342342+ */343343+static u8 dualshock4_bt_rdesc[] = {344344+ 0x05, 0x01, /* Usage Page (Desktop), */345345+ 0x09, 0x05, /* Usage (Gamepad), */346346+ 0xA1, 0x01, /* Collection (Application), */347347+ 0x85, 0x01, /* Report ID (1), */348348+ 0x75, 0x08, /* Report Size (8), */349349+ 0x95, 0x0A, /* Report Count (9), */350350+ 0x81, 0x02, /* Input (Variable), */351351+ 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */352352+ 0x85, 0x02, /* Report ID (2), */353353+ 0x09, 0x24, /* Usage (24h), */354354+ 0x95, 0x24, /* Report Count (36), */355355+ 0xB1, 0x02, /* Feature (Variable), */356356+ 0x85, 0xA3, /* Report ID (163), */357357+ 0x09, 0x25, /* Usage (25h), */358358+ 0x95, 0x30, /* Report Count (48), */359359+ 0xB1, 0x02, /* Feature (Variable), */360360+ 0x85, 0x05, /* Report ID (5), */361361+ 0x09, 0x26, /* Usage (26h), */362362+ 0x95, 0x28, /* Report Count (40), */363363+ 0xB1, 0x02, /* Feature (Variable), */364364+ 0x85, 0x06, /* Report ID (6), */365365+ 0x09, 0x27, /* Usage (27h), */366366+ 0x95, 0x34, /* Report Count (52), */367367+ 0xB1, 0x02, /* Feature (Variable), */368368+ 0x85, 0x07, /* Report ID (7), */369369+ 0x09, 0x28, /* Usage (28h), */370370+ 0x95, 0x30, /* Report Count (48), */371371+ 0xB1, 0x02, /* Feature (Variable), */372372+ 0x85, 0x08, /* Report ID (8), */373373+ 0x09, 0x29, /* Usage (29h), */374374+ 0x95, 0x2F, /* Report Count (47), */375375+ 0xB1, 0x02, /* Feature (Variable), */376376+ 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */377377+ 0x85, 0x03, /* Report ID (3), */378378+ 0x09, 0x21, /* Usage (21h), */379379+ 0x95, 0x26, /* Report Count (38), */380380+ 0xB1, 0x02, /* Feature (Variable), */381381+ 0x85, 0x04, /* Report ID (4), */382382+ 0x09, 0x22, /* Usage (22h), */383383+ 0x95, 0x2E, /* Report Count (46), */384384+ 0xB1, 0x02, /* Feature (Variable), */385385+ 0x85, 0xF0, /* Report ID (240), */386386+ 0x09, 0x47, /* Usage (47h), */387387+ 0x95, 0x3F, /* Report Count (63), */388388+ 0xB1, 0x02, /* Feature (Variable), */389389+ 0x85, 0xF1, /* Report ID (241), */390390+ 0x09, 0x48, /* Usage (48h), */391391+ 0x95, 0x3F, /* Report Count (63), */392392+ 0xB1, 0x02, /* Feature (Variable), */393393+ 0x85, 0xF2, /* Report ID (242), */394394+ 0x09, 0x49, /* Usage (49h), */395395+ 0x95, 0x0F, /* Report Count (15), */396396+ 0xB1, 0x02, /* Feature (Variable), */397397+ 0x85, 0x11, /* Report ID (17), */398398+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */399399+ 0x09, 0x20, /* Usage (20h), */400400+ 0x95, 0x02, /* Report Count (2), */401401+ 0x81, 0x02, /* Input (Variable), */402402+ 0x05, 0x01, /* Usage Page (Desktop), */403403+ 0x09, 0x30, /* Usage (X), */404404+ 0x09, 0x31, /* Usage (Y), */405405+ 0x09, 0x32, /* Usage (Z), */406406+ 0x09, 0x35, /* Usage (Rz), */407407+ 0x15, 0x00, /* Logical Minimum (0), */408408+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */409409+ 0x75, 0x08, /* Report Size (8), */410410+ 0x95, 0x04, /* Report Count (4), */411411+ 0x81, 0x02, /* Input (Variable), */412412+ 0x09, 0x39, /* Usage (Hat Switch), */413413+ 0x15, 0x00, /* Logical Minimum (0), */414414+ 0x25, 0x07, /* Logical Maximum (7), */415415+ 0x75, 0x04, /* Report Size (4), */416416+ 0x95, 0x01, /* Report Count (1), */417417+ 0x81, 0x42, /* Input (Variable, Null State), */418418+ 0x05, 0x09, /* Usage Page (Button), */419419+ 0x19, 0x01, /* Usage Minimum (01h), */420420+ 0x29, 0x0E, /* Usage Maximum (0Eh), */421421+ 0x15, 0x00, /* Logical Minimum (0), */422422+ 0x25, 0x01, /* Logical Maximum (1), */423423+ 0x75, 0x01, /* Report Size (1), */424424+ 0x95, 0x0E, /* Report Count (14), */425425+ 0x81, 0x02, /* Input (Variable), */426426+ 0x75, 0x06, /* Report Size (6), */427427+ 0x95, 0x01, /* Report Count (1), */428428+ 0x81, 0x01, /* Input (Constant), */429429+ 0x05, 0x01, /* Usage Page (Desktop), */430430+ 0x09, 0x33, /* Usage (Rx), */431431+ 0x09, 0x34, /* Usage (Ry), */432432+ 0x15, 0x00, /* Logical Minimum (0), */433433+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */434434+ 0x75, 0x08, /* Report Size (8), */435435+ 0x95, 0x02, /* Report Count (2), */436436+ 0x81, 0x02, /* Input (Variable), */437437+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */438438+ 0x09, 0x20, /* Usage (20h), */439439+ 0x95, 0x03, /* Report Count (3), */440440+ 0x81, 0x02, /* Input (Variable), */441441+ 0x05, 0x01, /* Usage Page (Desktop), */442442+ 0x19, 0x40, /* Usage Minimum (40h), */443443+ 0x29, 0x42, /* Usage Maximum (42h), */444444+ 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */445445+ 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */446446+ 0x75, 0x10, /* Report Size (16), */447447+ 0x95, 0x03, /* Report Count (3), */448448+ 0x81, 0x02, /* Input (Variable), */449449+ 0x19, 0x43, /* Usage Minimum (43h), */450450+ 0x29, 0x45, /* Usage Maximum (45h), */451451+ 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */452452+ 0x26, 0x00, 0x40, /* Logical Maximum (16384), */453453+ 0x95, 0x03, /* Report Count (3), */454454+ 0x81, 0x02, /* Input (Variable), */455455+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */456456+ 0x09, 0x20, /* Usage (20h), */457457+ 0x15, 0x00, /* Logical Minimum (0), */458458+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */459459+ 0x75, 0x08, /* Report Size (8), */460460+ 0x95, 0x31, /* Report Count (51), */461461+ 0x81, 0x02, /* Input (Variable), */462462+ 0x09, 0x21, /* Usage (21h), */463463+ 0x75, 0x08, /* Report Size (8), */464464+ 0x95, 0x4D, /* Report Count (77), */465465+ 0x91, 0x02, /* Output (Variable), */466466+ 0x85, 0x12, /* Report ID (18), */467467+ 0x09, 0x22, /* Usage (22h), */468468+ 0x95, 0x8D, /* Report Count (141), */469469+ 0x81, 0x02, /* Input (Variable), */470470+ 0x09, 0x23, /* Usage (23h), */471471+ 0x91, 0x02, /* Output (Variable), */472472+ 0x85, 0x13, /* Report ID (19), */473473+ 0x09, 0x24, /* Usage (24h), */474474+ 0x95, 0xCD, /* Report Count (205), */475475+ 0x81, 0x02, /* Input (Variable), */476476+ 0x09, 0x25, /* Usage (25h), */477477+ 0x91, 0x02, /* Output (Variable), */478478+ 0x85, 0x14, /* Report ID (20), */479479+ 0x09, 0x26, /* Usage (26h), */480480+ 0x96, 0x0D, 0x01, /* Report Count (269), */481481+ 0x81, 0x02, /* Input (Variable), */482482+ 0x09, 0x27, /* Usage (27h), */483483+ 0x91, 0x02, /* Output (Variable), */484484+ 0x85, 0x15, /* Report ID (21), */485485+ 0x09, 0x28, /* Usage (28h), */486486+ 0x96, 0x4D, 0x01, /* Report Count (333), */487487+ 0x81, 0x02, /* Input (Variable), */488488+ 0x09, 0x29, /* Usage (29h), */489489+ 0x91, 0x02, /* Output (Variable), */490490+ 0x85, 0x16, /* Report ID (22), */491491+ 0x09, 0x2A, /* Usage (2Ah), */492492+ 0x96, 0x8D, 0x01, /* Report Count (397), */493493+ 0x81, 0x02, /* Input (Variable), */494494+ 0x09, 0x2B, /* Usage (2Bh), */495495+ 0x91, 0x02, /* Output (Variable), */496496+ 0x85, 0x17, /* Report ID (23), */497497+ 0x09, 0x2C, /* Usage (2Ch), */498498+ 0x96, 0xCD, 0x01, /* Report Count (461), */499499+ 0x81, 0x02, /* Input (Variable), */500500+ 0x09, 0x2D, /* Usage (2Dh), */501501+ 0x91, 0x02, /* Output (Variable), */502502+ 0x85, 0x18, /* Report ID (24), */503503+ 0x09, 0x2E, /* Usage (2Eh), */504504+ 0x96, 0x0D, 0x02, /* Report Count (525), */505505+ 0x81, 0x02, /* Input (Variable), */506506+ 0x09, 0x2F, /* Usage (2Fh), */507507+ 0x91, 0x02, /* Output (Variable), */508508+ 0x85, 0x19, /* Report ID (25), */509509+ 0x09, 0x30, /* Usage (30h), */510510+ 0x96, 0x22, 0x02, /* Report Count (546), */511511+ 0x81, 0x02, /* Input (Variable), */512512+ 0x09, 0x31, /* Usage (31h), */513513+ 0x91, 0x02, /* Output (Variable), */514514+ 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */515515+ 0x85, 0x82, /* Report ID (130), */516516+ 0x09, 0x22, /* Usage (22h), */517517+ 0x95, 0x3F, /* Report Count (63), */518518+ 0xB1, 0x02, /* Feature (Variable), */519519+ 0x85, 0x83, /* Report ID (131), */520520+ 0x09, 0x23, /* Usage (23h), */521521+ 0xB1, 0x02, /* Feature (Variable), */522522+ 0x85, 0x84, /* Report ID (132), */523523+ 0x09, 0x24, /* Usage (24h), */524524+ 0xB1, 0x02, /* Feature (Variable), */525525+ 0x85, 0x90, /* Report ID (144), */526526+ 0x09, 0x30, /* Usage (30h), */527527+ 0xB1, 0x02, /* Feature (Variable), */528528+ 0x85, 0x91, /* Report ID (145), */529529+ 0x09, 0x31, /* Usage (31h), */530530+ 0xB1, 0x02, /* Feature (Variable), */531531+ 0x85, 0x92, /* Report ID (146), */532532+ 0x09, 0x32, /* Usage (32h), */533533+ 0xB1, 0x02, /* Feature (Variable), */534534+ 0x85, 0x93, /* Report ID (147), */535535+ 0x09, 0x33, /* Usage (33h), */536536+ 0xB1, 0x02, /* Feature (Variable), */537537+ 0x85, 0xA0, /* Report ID (160), */538538+ 0x09, 0x40, /* Usage (40h), */539539+ 0xB1, 0x02, /* Feature (Variable), */540540+ 0x85, 0xA4, /* Report ID (164), */541541+ 0x09, 0x44, /* Usage (44h), */542542+ 0xB1, 0x02, /* Feature (Variable), */543543+ 0xC0 /* End Collection */544544+};545545+347546static __u8 ps3remote_rdesc[] = {348547 0x05, 0x01, /* GUsagePage Generic Desktop */349548 0x09, 0x05, /* LUsage 0x05 [Game Pad] */···672449};673450674451static const unsigned int buzz_keymap[] = {675675- /* The controller has 4 remote buzzers, each with one LED and 5452452+ /*453453+ * The controller has 4 remote buzzers, each with one LED and 5676454 * buttons.677455 * 678456 * We use the mapping chosen by the controller, which is:···711487 [20] = BTN_TRIGGER_HAPPY20,712488};713489490490+static enum power_supply_property sony_battery_props[] = {491491+ POWER_SUPPLY_PROP_PRESENT,492492+ POWER_SUPPLY_PROP_CAPACITY,493493+ POWER_SUPPLY_PROP_SCOPE,494494+ POWER_SUPPLY_PROP_STATUS,495495+};496496+497497+static spinlock_t sony_dev_list_lock;498498+static LIST_HEAD(sony_device_list);499499+714500struct sony_sc {501501+ spinlock_t lock;502502+ struct list_head list_node;715503 struct hid_device *hdev;716504 struct led_classdev *leds[MAX_LEDS];717717- struct hid_report *output_report;718505 unsigned long quirks;719506 struct work_struct state_worker;507507+ struct power_supply battery;720508721509#ifdef CONFIG_SONY_FF722510 __u8 left;723511 __u8 right;724512#endif725513514514+ __u8 mac_address[6];515515+ __u8 worker_initialized;516516+ __u8 cable_state;517517+ __u8 battery_charging;518518+ __u8 battery_capacity;726519 __u8 led_state[MAX_LEDS];727520 __u8 led_count;728521};···817576 hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");818577 rdesc = dualshock4_usb_rdesc;819578 *rsize = sizeof(dualshock4_usb_rdesc);579579+ } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {580580+ hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");581581+ rdesc = dualshock4_bt_rdesc;582582+ *rsize = sizeof(dualshock4_bt_rdesc);820583 }821584822585 /* The HID descriptor exposed over BT has a trailing zero byte */···844599 return rdesc;845600}846601602602+static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)603603+{604604+ static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };605605+ unsigned long flags;606606+ __u8 cable_state, battery_capacity, battery_charging;607607+608608+ /*609609+ * The sixaxis is charging if the battery value is 0xee610610+ * and it is fully charged if the value is 0xef.611611+ * It does not report the actual level while charging so it612612+ * is set to 100% while charging is in progress.613613+ */614614+ if (rd[30] >= 0xee) {615615+ battery_capacity = 100;616616+ battery_charging = !(rd[30] & 0x01);617617+ } else {618618+ __u8 index = rd[30] <= 5 ? rd[30] : 5;619619+ battery_capacity = sixaxis_battery_capacity[index];620620+ battery_charging = 0;621621+ }622622+ cable_state = !((rd[31] >> 4) & 0x01);623623+624624+ spin_lock_irqsave(&sc->lock, flags);625625+ sc->cable_state = cable_state;626626+ sc->battery_capacity = battery_capacity;627627+ sc->battery_charging = battery_charging;628628+ spin_unlock_irqrestore(&sc->lock, flags);629629+}630630+631631+static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)632632+{633633+ struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,634634+ struct hid_input, list);635635+ struct input_dev *input_dev = hidinput->input;636636+ unsigned long flags;637637+ int n, offset;638638+ __u8 cable_state, battery_capacity, battery_charging;639639+640640+ /*641641+ * Battery and touchpad data starts at byte 30 in the USB report and642642+ * 32 in Bluetooth report.643643+ */644644+ offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;645645+646646+ /*647647+ * The lower 4 bits of byte 30 contain the battery level648648+ * and the 5th bit contains the USB cable state.649649+ */650650+ cable_state = (rd[offset] >> 4) & 0x01;651651+ battery_capacity = rd[offset] & 0x0F;652652+653653+ /*654654+ * When a USB power source is connected the battery level ranges from655655+ * 0 to 10, and when running on battery power it ranges from 0 to 9.656656+ * A battery level above 10 when plugged in means charge completed.657657+ */658658+ if (!cable_state || battery_capacity > 10)659659+ battery_charging = 0;660660+ else661661+ battery_charging = 1;662662+663663+ if (!cable_state)664664+ battery_capacity++;665665+ if (battery_capacity > 10)666666+ battery_capacity = 10;667667+668668+ battery_capacity *= 10;669669+670670+ spin_lock_irqsave(&sc->lock, flags);671671+ sc->cable_state = cable_state;672672+ sc->battery_capacity = battery_capacity;673673+ sc->battery_charging = battery_charging;674674+ spin_unlock_irqrestore(&sc->lock, flags);675675+676676+ offset += 5;677677+678678+ /*679679+ * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB680680+ * and 37 on Bluetooth.681681+ * The first 7 bits of the first byte is a counter and bit 8 is a touch682682+ * indicator that is 0 when pressed and 1 when not pressed.683683+ * The next 3 bytes are two 12 bit touch coordinates, X and Y.684684+ * The data for the second touch is in the same format and immediatly685685+ * follows the data for the first.686686+ */687687+ for (n = 0; n < 2; n++) {688688+ __u16 x, y;689689+690690+ x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);691691+ y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);692692+693693+ input_mt_slot(input_dev, n);694694+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,695695+ !(rd[offset] >> 7));696696+ input_report_abs(input_dev, ABS_MT_POSITION_X, x);697697+ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);698698+699699+ offset += 4;700700+ }701701+}702702+847703static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,848704 __u8 *rd, int size)849705{850706 struct sony_sc *sc = hid_get_drvdata(hdev);851707852852- /* Sixaxis HID report has acclerometers/gyro with MSByte first, this708708+ /*709709+ * Sixaxis HID report has acclerometers/gyro with MSByte first, this853710 * has to be BYTE_SWAPPED before passing up to joystick interface854711 */855855- if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) &&856856- rd[0] == 0x01 && size == 49) {712712+ if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {857713 swap(rd[41], rd[42]);858714 swap(rd[43], rd[44]);859715 swap(rd[45], rd[46]);860716 swap(rd[47], rd[48]);717717+718718+ sixaxis_parse_report(sc, rd, size);719719+ } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&720720+ size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)721721+ && rd[0] == 0x11 && size == 78)) {722722+ dualshock4_parse_report(sc, rd, size);861723 }862724863725 return 0;···1076724 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);1077725}1078726727727+/*728728+ * Requesting feature report 0x02 in Bluetooth mode changes the state of the729729+ * controller so that it sends full input reports of type 0x11.730730+ */731731+static int dualshock4_set_operational_bt(struct hid_device *hdev)732732+{733733+ __u8 buf[37] = { 0 };734734+735735+ return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),736736+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);737737+}738738+1079739static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)1080740{1081741 struct list_head *report_list =···11157511116752 if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {1117753 buzz_set_leds(hdev, leds);11181118- } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) ||11191119- (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) {754754+ } else {1120755 for (n = 0; n < count; n++)1121756 drv_data->led_state[n] = leds[n];1122757 schedule_work(&drv_data->state_worker);···1155792 struct sony_sc *drv_data;11567931157794 int n;11581158- int on = 0;11597951160796 drv_data = hid_get_drvdata(hdev);1161797 if (!drv_data) {···1163801 }11648021165803 for (n = 0; n < drv_data->led_count; n++) {11661166- if (led == drv_data->leds[n]) {11671167- on = !!(drv_data->led_state[n]);11681168- break;11691169- }804804+ if (led == drv_data->leds[n])805805+ return drv_data->led_state[n];1170806 }117180711721172- return on ? LED_FULL : LED_OFF;808808+ return LED_OFF;1173809}11748101175811static void sony_leds_remove(struct hid_device *hdev)···1217857 /* Validate expected report characteristics. */1218858 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))1219859 return -ENODEV;12201220- } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) {860860+ } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {1221861 drv_data->led_count = 3;1222862 max_brightness = 255;1223863 use_colors = 1;···1231871 name_fmt = "%s::sony%d";1232872 }123387312341234- /* Clear LEDs as we have no way of reading their initial state. This is874874+ /*875875+ * Clear LEDs as we have no way of reading their initial state. This is1235876 * only relevant if the driver is loaded after somebody actively set the12361236- * LEDs to on */877877+ * LEDs to on878878+ */1237879 sony_set_leds(hdev, initial_values, drv_data->led_count);12388801239881 name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;···1305943 buf[10] |= sc->led_state[2] << 3;1306944 buf[10] |= sc->led_state[3] << 4;130794513081308- hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT);946946+ if (sc->quirks & SIXAXIS_CONTROLLER_USB)947947+ hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT);948948+ else949949+ hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf),950950+ HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);1309951}13109521311953static void dualshock4_state_worker(struct work_struct *work)1312954{1313955 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);1314956 struct hid_device *hdev = sc->hdev;13151315- struct hid_report *report = sc->output_report;13161316- __s32 *value = report->field[0]->value;957957+ int offset;131795813181318- value[0] = 0x03;959959+ __u8 buf[78] = { 0 };960960+961961+ if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {962962+ buf[0] = 0x05;963963+ buf[1] = 0x03;964964+ offset = 4;965965+ } else {966966+ buf[0] = 0x11;967967+ buf[1] = 0xB0;968968+ buf[3] = 0x0F;969969+ offset = 6;970970+ }13199711320972#ifdef CONFIG_SONY_FF13211321- value[3] = sc->right;13221322- value[4] = sc->left;973973+ buf[offset++] = sc->right;974974+ buf[offset++] = sc->left;975975+#else976976+ offset += 2;1323977#endif132497813251325- value[5] = sc->led_state[0];13261326- value[6] = sc->led_state[1];13271327- value[7] = sc->led_state[2];979979+ buf[offset++] = sc->led_state[0];980980+ buf[offset++] = sc->led_state[1];981981+ buf[offset++] = sc->led_state[2];132898213291329- hid_hw_request(hdev, report, HID_REQ_SET_REPORT);983983+ if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)984984+ hid_hw_output_report(hdev, buf, 32);985985+ else986986+ hid_hw_raw_request(hdev, 0x11, buf, 78,987987+ HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);1330988}13319891332990#ifdef CONFIG_SONY_FF···1376994 return input_ff_create_memless(input_dev, NULL, sony_play_effect);1377995}137899613791379-static void sony_destroy_ff(struct hid_device *hdev)13801380-{13811381- struct sony_sc *sc = hid_get_drvdata(hdev);13821382-13831383- cancel_work_sync(&sc->state_worker);13841384-}13851385-1386997#else1387998static int sony_init_ff(struct hid_device *hdev)1388999{13891000 return 0;13901001}1391100213921392-static void sony_destroy_ff(struct hid_device *hdev)13931393-{13941394-}13951003#endif1396100413971397-static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size)10051005+static int sony_battery_get_property(struct power_supply *psy,10061006+ enum power_supply_property psp,10071007+ union power_supply_propval *val)13981008{13991399- struct list_head *head, *list;14001400- struct hid_report *report;10091009+ struct sony_sc *sc = container_of(psy, struct sony_sc, battery);10101010+ unsigned long flags;10111011+ int ret = 0;10121012+ u8 battery_charging, battery_capacity, cable_state;10131013+10141014+ spin_lock_irqsave(&sc->lock, flags);10151015+ battery_charging = sc->battery_charging;10161016+ battery_capacity = sc->battery_capacity;10171017+ cable_state = sc->cable_state;10181018+ spin_unlock_irqrestore(&sc->lock, flags);10191019+10201020+ switch (psp) {10211021+ case POWER_SUPPLY_PROP_PRESENT:10221022+ val->intval = 1;10231023+ break;10241024+ case POWER_SUPPLY_PROP_SCOPE:10251025+ val->intval = POWER_SUPPLY_SCOPE_DEVICE;10261026+ break;10271027+ case POWER_SUPPLY_PROP_CAPACITY:10281028+ val->intval = battery_capacity;10291029+ break;10301030+ case POWER_SUPPLY_PROP_STATUS:10311031+ if (battery_charging)10321032+ val->intval = POWER_SUPPLY_STATUS_CHARGING;10331033+ else10341034+ if (battery_capacity == 100 && cable_state)10351035+ val->intval = POWER_SUPPLY_STATUS_FULL;10361036+ else10371037+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;10381038+ break;10391039+ default:10401040+ ret = -EINVAL;10411041+ break;10421042+ }10431043+ return ret;10441044+}10451045+10461046+static int sony_battery_probe(struct sony_sc *sc)10471047+{10481048+ static atomic_t power_id_seq = ATOMIC_INIT(0);10491049+ unsigned long power_id;14011050 struct hid_device *hdev = sc->hdev;10511051+ int ret;1402105214031403- list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list;10531053+ /*10541054+ * Set the default battery level to 100% to avoid low battery warnings10551055+ * if the battery is polled before the first device report is received.10561056+ */10571057+ sc->battery_capacity = 100;1404105814051405- list_for_each(head, list) {14061406- report = list_entry(head, struct hid_report, list);10591059+ power_id = (unsigned long)atomic_inc_return(&power_id_seq);1407106014081408- if (report->id == req_id) {14091409- if (report->size < req_size) {14101410- hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n",14111411- req_id, report->size, req_size);14121412- return -EINVAL;14131413- }14141414- sc->output_report = report;14151415- return 0;10611061+ sc->battery.properties = sony_battery_props;10621062+ sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);10631063+ sc->battery.get_property = sony_battery_get_property;10641064+ sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;10651065+ sc->battery.use_for_apm = 0;10661066+ sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",10671067+ power_id);10681068+ if (!sc->battery.name)10691069+ return -ENOMEM;10701070+10711071+ ret = power_supply_register(&hdev->dev, &sc->battery);10721072+ if (ret) {10731073+ hid_err(hdev, "Unable to register battery device\n");10741074+ goto err_free;10751075+ }10761076+10771077+ power_supply_powers(&sc->battery, &hdev->dev);10781078+ return 0;10791079+10801080+err_free:10811081+ kfree(sc->battery.name);10821082+ sc->battery.name = NULL;10831083+ return ret;10841084+}10851085+10861086+static void sony_battery_remove(struct sony_sc *sc)10871087+{10881088+ if (!sc->battery.name)10891089+ return;10901090+10911091+ power_supply_unregister(&sc->battery);10921092+ kfree(sc->battery.name);10931093+ sc->battery.name = NULL;10941094+}10951095+10961096+static int sony_register_touchpad(struct sony_sc *sc, int touch_count,10971097+ int w, int h)10981098+{10991099+ struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,11001100+ struct hid_input, list);11011101+ struct input_dev *input_dev = hidinput->input;11021102+ int ret;11031103+11041104+ ret = input_mt_init_slots(input_dev, touch_count, 0);11051105+ if (ret < 0) {11061106+ hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");11071107+ return ret;11081108+ }11091109+11101110+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);11111111+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);11121112+11131113+ return 0;11141114+}11151115+11161116+/*11171117+ * If a controller is plugged in via USB while already connected via Bluetooth11181118+ * it will show up as two devices. A global list of connected controllers and11191119+ * their MAC addresses is maintained to ensure that a device is only connected11201120+ * once.11211121+ */11221122+static int sony_check_add_dev_list(struct sony_sc *sc)11231123+{11241124+ struct sony_sc *entry;11251125+ unsigned long flags;11261126+ int ret;11271127+11281128+ spin_lock_irqsave(&sony_dev_list_lock, flags);11291129+11301130+ list_for_each_entry(entry, &sony_device_list, list_node) {11311131+ ret = memcmp(sc->mac_address, entry->mac_address,11321132+ sizeof(sc->mac_address));11331133+ if (!ret) {11341134+ ret = -EEXIST;11351135+ hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",11361136+ sc->mac_address);11371137+ goto unlock;14161138 }14171139 }1418114014191419- hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id);11411141+ ret = 0;11421142+ list_add(&(sc->list_node), &sony_device_list);1420114314211421- return -EINVAL;11441144+unlock:11451145+ spin_unlock_irqrestore(&sony_dev_list_lock, flags);11461146+ return ret;14221147}11481148+11491149+static void sony_remove_dev_list(struct sony_sc *sc)11501150+{11511151+ unsigned long flags;11521152+11531153+ if (sc->list_node.next) {11541154+ spin_lock_irqsave(&sony_dev_list_lock, flags);11551155+ list_del(&(sc->list_node));11561156+ spin_unlock_irqrestore(&sony_dev_list_lock, flags);11571157+ }11581158+}11591159+11601160+static int sony_get_bt_devaddr(struct sony_sc *sc)11611161+{11621162+ int ret;11631163+11641164+ /* HIDP stores the device MAC address as a string in the uniq field. */11651165+ ret = strlen(sc->hdev->uniq);11661166+ if (ret != 17)11671167+ return -EINVAL;11681168+11691169+ ret = sscanf(sc->hdev->uniq,11701170+ "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",11711171+ &sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],11721172+ &sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);11731173+11741174+ if (ret != 6)11751175+ return -EINVAL;11761176+11771177+ return 0;11781178+}11791179+11801180+static int sony_check_add(struct sony_sc *sc)11811181+{11821182+ int n, ret;11831183+11841184+ if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||11851185+ (sc->quirks & SIXAXIS_CONTROLLER_BT)) {11861186+ /*11871187+ * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC11881188+ * address from the uniq string where HIDP stores it.11891189+ * As uniq cannot be guaranteed to be a MAC address in all cases11901190+ * a failure of this function should not prevent the connection.11911191+ */11921192+ if (sony_get_bt_devaddr(sc) < 0) {11931193+ hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");11941194+ return 0;11951195+ }11961196+ } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {11971197+ __u8 buf[7];11981198+11991199+ /*12001200+ * The MAC address of a DS4 controller connected via USB can be12011201+ * retrieved with feature report 0x81. The address begins at12021202+ * offset 1.12031203+ */12041204+ ret = hid_hw_raw_request(sc->hdev, 0x81, buf, sizeof(buf),12051205+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);12061206+12071207+ if (ret != 7) {12081208+ hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");12091209+ return ret < 0 ? ret : -EINVAL;12101210+ }12111211+12121212+ memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));12131213+ } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {12141214+ __u8 buf[18];12151215+12161216+ /*12171217+ * The MAC address of a Sixaxis controller connected via USB can12181218+ * be retrieved with feature report 0xf2. The address begins at12191219+ * offset 4.12201220+ */12211221+ ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, sizeof(buf),12221222+ HID_FEATURE_REPORT, HID_REQ_GET_REPORT);12231223+12241224+ if (ret != 18) {12251225+ hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");12261226+ return ret < 0 ? ret : -EINVAL;12271227+ }12281228+12291229+ /*12301230+ * The Sixaxis device MAC in the report is big-endian and must12311231+ * be byte-swapped.12321232+ */12331233+ for (n = 0; n < 6; n++)12341234+ sc->mac_address[5-n] = buf[4+n];12351235+ } else {12361236+ return 0;12371237+ }12381238+12391239+ return sony_check_add_dev_list(sc);12401240+}12411241+1423124214241243static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)14251244{···16611078 if (sc->quirks & SIXAXIS_CONTROLLER_USB) {16621079 hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;16631080 ret = sixaxis_set_operational_usb(hdev);10811081+ sc->worker_initialized = 1;16641082 INIT_WORK(&sc->state_worker, sixaxis_state_worker);16651665- }16661666- else if (sc->quirks & SIXAXIS_CONTROLLER_BT)10831083+ } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {16671084 ret = sixaxis_set_operational_bt(hdev);16681668- else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {16691669- /* Report 5 (31 bytes) is used to send data to the controller via USB */16701670- ret = sony_set_output_report(sc, 0x05, 248);10851085+ sc->worker_initialized = 1;10861086+ INIT_WORK(&sc->state_worker, sixaxis_state_worker);10871087+ } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {10881088+ if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {10891089+ ret = dualshock4_set_operational_bt(hdev);10901090+ if (ret < 0) {10911091+ hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");10921092+ goto err_stop;10931093+ }10941094+ }10951095+ /*10961096+ * The Dualshock 4 touchpad supports 2 touches and has a10971097+ * resolution of 1920x940.10981098+ */10991099+ ret = sony_register_touchpad(sc, 2, 1920, 940);16711100 if (ret < 0)16721101 goto err_stop;1673110211031103+ sc->worker_initialized = 1;16741104 INIT_WORK(&sc->state_worker, dualshock4_state_worker);16751105 } else {16761106 ret = 0;16771107 }1678110811091109+ if (ret < 0)11101110+ goto err_stop;11111111+11121112+ ret = sony_check_add(sc);16791113 if (ret < 0)16801114 goto err_stop;16811115···17021102 goto err_stop;17031103 }1704110417051705- ret = sony_init_ff(hdev);17061706- if (ret < 0)17071707- goto err_stop;11051105+ if (sc->quirks & SONY_BATTERY_SUPPORT) {11061106+ ret = sony_battery_probe(sc);11071107+ if (ret < 0)11081108+ goto err_stop;11091109+11101110+ /* Open the device to receive reports with battery info */11111111+ ret = hid_hw_open(hdev);11121112+ if (ret < 0) {11131113+ hid_err(hdev, "hw open failed\n");11141114+ goto err_stop;11151115+ }11161116+ }11171117+11181118+ if (sc->quirks & SONY_FF_SUPPORT) {11191119+ ret = sony_init_ff(hdev);11201120+ if (ret < 0)11211121+ goto err_close;11221122+ }1708112317091124 return 0;11251125+err_close:11261126+ hid_hw_close(hdev);17101127err_stop:17111128 if (sc->quirks & SONY_LED_SUPPORT)17121129 sony_leds_remove(hdev);11301130+ if (sc->quirks & SONY_BATTERY_SUPPORT)11311131+ sony_battery_remove(sc);11321132+ if (sc->worker_initialized)11331133+ cancel_work_sync(&sc->state_worker);11341134+ sony_remove_dev_list(sc);17131135 hid_hw_stop(hdev);17141136 return ret;17151137}···17431121 if (sc->quirks & SONY_LED_SUPPORT)17441122 sony_leds_remove(hdev);1745112317461746- sony_destroy_ff(hdev);11241124+ if (sc->quirks & SONY_BATTERY_SUPPORT) {11251125+ hid_hw_close(hdev);11261126+ sony_battery_remove(sc);11271127+ }11281128+11291129+ if (sc->worker_initialized)11301130+ cancel_work_sync(&sc->state_worker);11311131+11321132+ sony_remove_dev_list(sc);1747113317481134 hid_hw_stop(hdev);17491135}
+3
net/bluetooth/hidp/core.c
···767767 snprintf(hid->phys, sizeof(hid->phys), "%pMR",768768 &l2cap_pi(session->ctrl_sock->sk)->chan->src);769769770770+ /* NOTE: Some device modules depend on the dst address being stored in771771+ * uniq. Please be aware of this before making changes to this behavior.772772+ */770773 snprintf(hid->uniq, sizeof(hid->uniq), "%pMR",771774 &l2cap_pi(session->ctrl_sock->sk)->chan->dst);772775