aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-sony.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-sony.c')
-rw-r--r--drivers/hid/hid-sony.c132
1 files changed, 86 insertions, 46 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2259eaa8b988..c372368e438c 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -56,32 +56,81 @@
56 56
57#define MAX_LEDS 4 57#define MAX_LEDS 4
58 58
59static const u8 sixaxis_rdesc_fixup[] = { 59static __u8 sixaxis_rdesc[] = {
60 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C, 60 0x05, 0x01, /* Usage Page (Desktop), */
61 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF, 61 0x09, 0x04, /* Usage (Joystik), */
62 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 62 0xA1, 0x01, /* Collection (Application), */
63}; 63 0xA1, 0x02, /* Collection (Logical), */
64 64 0x85, 0x01, /* Report ID (1), */
65static const u8 sixaxis_rdesc_fixup2[] = { 65 0x75, 0x08, /* Report Size (8), */
66 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, 66 0x95, 0x01, /* Report Count (1), */
67 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 67 0x15, 0x00, /* Logical Minimum (0), */
68 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, 68 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
69 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, 69 0x81, 0x03, /* Input (Constant, Variable), */
70 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, 70 0x75, 0x01, /* Report Size (1), */
71 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, 71 0x95, 0x13, /* Report Count (19), */
72 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 72 0x15, 0x00, /* Logical Minimum (0), */
73 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, 73 0x25, 0x01, /* Logical Maximum (1), */
74 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, 74 0x35, 0x00, /* Physical Minimum (0), */
75 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, 75 0x45, 0x01, /* Physical Maximum (1), */
76 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, 76 0x05, 0x09, /* Usage Page (Button), */
77 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, 77 0x19, 0x01, /* Usage Minimum (01h), */
78 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, 78 0x29, 0x13, /* Usage Maximum (13h), */
79 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, 79 0x81, 0x02, /* Input (Variable), */
80 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, 80 0x75, 0x01, /* Report Size (1), */
81 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, 81 0x95, 0x0D, /* Report Count (13), */
82 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, 82 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
83 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 83 0x81, 0x03, /* Input (Constant, Variable), */
84 0xb1, 0x02, 0xc0, 0xc0, 84 0x15, 0x00, /* Logical Minimum (0), */
85 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
86 0x05, 0x01, /* Usage Page (Desktop), */
87 0x09, 0x01, /* Usage (Pointer), */
88 0xA1, 0x00, /* Collection (Physical), */
89 0x75, 0x08, /* Report Size (8), */
90 0x95, 0x04, /* Report Count (4), */
91 0x35, 0x00, /* Physical Minimum (0), */
92 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
93 0x09, 0x30, /* Usage (X), */
94 0x09, 0x31, /* Usage (Y), */
95 0x09, 0x32, /* Usage (Z), */
96 0x09, 0x35, /* Usage (Rz), */
97 0x81, 0x02, /* Input (Variable), */
98 0xC0, /* End Collection, */
99 0x05, 0x01, /* Usage Page (Desktop), */
100 0x95, 0x13, /* Report Count (19), */
101 0x09, 0x01, /* Usage (Pointer), */
102 0x81, 0x02, /* Input (Variable), */
103 0x95, 0x0C, /* Report Count (12), */
104 0x81, 0x01, /* Input (Constant), */
105 0x75, 0x10, /* Report Size (16), */
106 0x95, 0x04, /* Report Count (4), */
107 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
108 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
109 0x09, 0x01, /* Usage (Pointer), */
110 0x81, 0x02, /* Input (Variable), */
111 0xC0, /* End Collection, */
112 0xA1, 0x02, /* Collection (Logical), */
113 0x85, 0x02, /* Report ID (2), */
114 0x75, 0x08, /* Report Size (8), */
115 0x95, 0x30, /* Report Count (48), */
116 0x09, 0x01, /* Usage (Pointer), */
117 0xB1, 0x02, /* Feature (Variable), */
118 0xC0, /* End Collection, */
119 0xA1, 0x02, /* Collection (Logical), */
120 0x85, 0xEE, /* Report ID (238), */
121 0x75, 0x08, /* Report Size (8), */
122 0x95, 0x30, /* Report Count (48), */
123 0x09, 0x01, /* Usage (Pointer), */
124 0xB1, 0x02, /* Feature (Variable), */
125 0xC0, /* End Collection, */
126 0xA1, 0x02, /* Collection (Logical), */
127 0x85, 0xEF, /* Report ID (239), */
128 0x75, 0x08, /* Report Size (8), */
129 0x95, 0x30, /* Report Count (48), */
130 0x09, 0x01, /* Usage (Pointer), */
131 0xB1, 0x02, /* Feature (Variable), */
132 0xC0, /* End Collection, */
133 0xC0 /* End Collection */
85}; 134};
86 135
87/* 136/*
@@ -778,6 +827,13 @@ struct sony_sc {
778 __u8 led_count; 827 __u8 led_count;
779}; 828};
780 829
830static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
831 unsigned int *rsize)
832{
833 *rsize = sizeof(sixaxis_rdesc);
834 return sixaxis_rdesc;
835}
836
781static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 837static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
782 unsigned int *rsize) 838 unsigned int *rsize)
783{ 839{
@@ -819,8 +875,6 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
819 return 1; 875 return 1;
820} 876}
821 877
822
823/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
824static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 878static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
825 unsigned int *rsize) 879 unsigned int *rsize)
826{ 880{
@@ -857,20 +911,8 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
857 *rsize = sizeof(dualshock4_bt_rdesc); 911 *rsize = sizeof(dualshock4_bt_rdesc);
858 } 912 }
859 913
860 /* The HID descriptor exposed over BT has a trailing zero byte */ 914 if (sc->quirks & SIXAXIS_CONTROLLER)
861 if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) || 915 return sixaxis_fixup(hdev, rdesc, rsize);
862 ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
863 rdesc[83] == 0x75) {
864 hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
865 memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
866 sizeof(sixaxis_rdesc_fixup));
867 } else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
868 *rsize > sizeof(sixaxis_rdesc_fixup2)) {
869 hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
870 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
871 *rsize = sizeof(sixaxis_rdesc_fixup2);
872 memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
873 }
874 916
875 if (sc->quirks & PS3REMOTE) 917 if (sc->quirks & PS3REMOTE)
876 return ps3remote_fixup(hdev, rdesc, rsize); 918 return ps3remote_fixup(hdev, rdesc, rsize);
@@ -1307,7 +1349,7 @@ static int sony_leds_init(struct sony_sc *sc)
1307 static const char * const ds4_name_str[] = { "red", "green", "blue", 1349 static const char * const ds4_name_str[] = { "red", "green", "blue",
1308 "global" }; 1350 "global" };
1309 __u8 initial_values[MAX_LEDS] = { 0 }; 1351 __u8 initial_values[MAX_LEDS] = { 0 };
1310 __u8 max_brightness[MAX_LEDS] = { 1 }; 1352 __u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
1311 __u8 use_hw_blink[MAX_LEDS] = { 0 }; 1353 __u8 use_hw_blink[MAX_LEDS] = { 0 };
1312 1354
1313 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1355 BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
@@ -1830,9 +1872,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1830 1872
1831 if (sc->quirks & VAIO_RDESC_CONSTANT) 1873 if (sc->quirks & VAIO_RDESC_CONSTANT)
1832 connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1874 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1833 else if (sc->quirks & SIXAXIS_CONTROLLER_USB) 1875 else if (sc->quirks & SIXAXIS_CONTROLLER)
1834 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1835 else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
1836 connect_mask |= HID_CONNECT_HIDDEV_FORCE; 1876 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1837 1877
1838 ret = hid_hw_start(hdev, connect_mask); 1878 ret = hid_hw_start(hdev, connect_mask);