aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Praznik <frank.praznik@oh.rr.com>2015-05-05 20:47:30 -0400
committerJiri Kosina <jkosina@suse.cz>2015-05-07 04:41:35 -0400
commitc5e0c1c4950f9126f7eb2fb1d3f8aa4080f05538 (patch)
tree89bbf962abc0b4cb9b1f9227f0a457c013e8b6d1
parent7c886d098d6128438e706ca4c068b8920fdac42d (diff)
HID: sony: Add support for the Sony Motion Controller
Add a fixed-up HID descriptor for the Sony motion controller and enable controls for the LED light as well as force-feedback. The LED is multi-colored (red, green, blue). The motion controller has a single rumble motor so the higher of the left and right values is used to set the speed. Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-sony.c138
1 files changed, 136 insertions, 2 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 4c521b2c6a82..d0b18a5779d7 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -46,14 +46,16 @@
46#define PS3REMOTE BIT(4) 46#define PS3REMOTE BIT(4)
47#define DUALSHOCK4_CONTROLLER_USB BIT(5) 47#define DUALSHOCK4_CONTROLLER_USB BIT(5)
48#define DUALSHOCK4_CONTROLLER_BT BIT(6) 48#define DUALSHOCK4_CONTROLLER_BT BIT(6)
49#define MOTION_CONTROLLER BIT(7)
49 50
50#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 51#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
51#define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ 52#define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
52 DUALSHOCK4_CONTROLLER_BT) 53 DUALSHOCK4_CONTROLLER_BT)
53#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 54#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
54 DUALSHOCK4_CONTROLLER) 55 DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER)
55#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 56#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
56#define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) 57#define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
58 MOTION_CONTROLLER)
57 59
58#define MAX_LEDS 4 60#define MAX_LEDS 4
59 61
@@ -134,6 +136,85 @@ static __u8 sixaxis_rdesc[] = {
134 0xC0 /* End Collection */ 136 0xC0 /* End Collection */
135}; 137};
136 138
139/* PS/3 Motion controller */
140static __u8 motion_rdesc[] = {
141 0x05, 0x01, /* Usage Page (Desktop), */
142 0x09, 0x04, /* Usage (Joystick), */
143 0xA1, 0x01, /* Collection (Application), */
144 0xA1, 0x02, /* Collection (Logical), */
145 0x85, 0x01, /* Report ID (1), */
146 0x75, 0x08, /* Report Size (8), */
147 0x95, 0x01, /* Report Count (1), */
148 0x15, 0x00, /* Logical Minimum (0), */
149 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
150 0x81, 0x03, /* Input (Constant, Variable), */
151 0x75, 0x01, /* Report Size (1), */
152 0x95, 0x13, /* Report Count (19), */
153 0x15, 0x00, /* Logical Minimum (0), */
154 0x25, 0x01, /* Logical Maximum (1), */
155 0x35, 0x00, /* Physical Minimum (0), */
156 0x45, 0x01, /* Physical Maximum (1), */
157 0x05, 0x09, /* Usage Page (Button), */
158 0x19, 0x01, /* Usage Minimum (01h), */
159 0x29, 0x13, /* Usage Maximum (13h), */
160 0x81, 0x02, /* Input (Variable), */
161 0x75, 0x01, /* Report Size (1), */
162 0x95, 0x0D, /* Report Count (13), */
163 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
164 0x81, 0x03, /* Input (Constant, Variable), */
165 0x15, 0x00, /* Logical Minimum (0), */
166 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
167 0x05, 0x01, /* Usage Page (Desktop), */
168 0x09, 0x01, /* Usage (Pointer), */
169 0xA1, 0x00, /* Collection (Physical), */
170 0x75, 0x08, /* Report Size (8), */
171 0x95, 0x04, /* Report Count (4), */
172 0x35, 0x00, /* Physical Minimum (0), */
173 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
174 0x09, 0x30, /* Usage (X), */
175 0x09, 0x31, /* Usage (Y), */
176 0x09, 0x32, /* Usage (Z), */
177 0x09, 0x35, /* Usage (Rz), */
178 0x81, 0x02, /* Input (Variable), */
179 0xC0, /* End Collection, */
180 0x05, 0x01, /* Usage Page (Desktop), */
181 0x95, 0x13, /* Report Count (19), */
182 0x09, 0x01, /* Usage (Pointer), */
183 0x81, 0x02, /* Input (Variable), */
184 0x95, 0x0C, /* Report Count (12), */
185 0x81, 0x01, /* Input (Constant), */
186 0x75, 0x10, /* Report Size (16), */
187 0x95, 0x04, /* Report Count (4), */
188 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
189 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
190 0x09, 0x01, /* Usage (Pointer), */
191 0x81, 0x02, /* Input (Variable), */
192 0xC0, /* End Collection, */
193 0xA1, 0x02, /* Collection (Logical), */
194 0x85, 0x02, /* Report ID (2), */
195 0x75, 0x08, /* Report Size (8), */
196 0x95, 0x30, /* Report Count (48), */
197 0x09, 0x01, /* Usage (Pointer), */
198 0xB1, 0x02, /* Feature (Variable), */
199 0xC0, /* End Collection, */
200 0xA1, 0x02, /* Collection (Logical), */
201 0x85, 0xEE, /* Report ID (238), */
202 0x75, 0x08, /* Report Size (8), */
203 0x95, 0x30, /* Report Count (48), */
204 0x09, 0x01, /* Usage (Pointer), */
205 0xB1, 0x02, /* Feature (Variable), */
206 0xC0, /* End Collection, */
207 0xA1, 0x02, /* Collection (Logical), */
208 0x85, 0xEF, /* Report ID (239), */
209 0x75, 0x08, /* Report Size (8), */
210 0x95, 0x30, /* Report Count (48), */
211 0x09, 0x01, /* Usage (Pointer), */
212 0xB1, 0x02, /* Feature (Variable), */
213 0xC0, /* End Collection, */
214 0xC0 /* End Collection */
215};
216
217
137/* 218/*
138 * The default descriptor doesn't provide mapping for the accelerometers 219 * The default descriptor doesn't provide mapping for the accelerometers
139 * or orientation sensors. This fixed descriptor maps the accelerometers 220 * or orientation sensors. This fixed descriptor maps the accelerometers
@@ -798,6 +879,13 @@ union sixaxis_output_report_01 {
798 __u8 buf[36]; 879 __u8 buf[36];
799}; 880};
800 881
882struct motion_output_report_02 {
883 u8 type, zero;
884 u8 r, g, b;
885 u8 zero2;
886 u8 rumble;
887};
888
801#define DS4_REPORT_0x02_SIZE 37 889#define DS4_REPORT_0x02_SIZE 37
802#define DS4_REPORT_0x05_SIZE 32 890#define DS4_REPORT_0x05_SIZE 32
803#define DS4_REPORT_0x11_SIZE 78 891#define DS4_REPORT_0x11_SIZE 78
@@ -844,6 +932,13 @@ static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
844 return sixaxis_rdesc; 932 return sixaxis_rdesc;
845} 933}
846 934
935static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
936 unsigned int *rsize)
937{
938 *rsize = sizeof(motion_rdesc);
939 return motion_rdesc;
940}
941
847static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 942static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
848 unsigned int *rsize) 943 unsigned int *rsize)
849{ 944{
@@ -924,6 +1019,9 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
924 if (sc->quirks & SIXAXIS_CONTROLLER) 1019 if (sc->quirks & SIXAXIS_CONTROLLER)
925 return sixaxis_fixup(hdev, rdesc, rsize); 1020 return sixaxis_fixup(hdev, rdesc, rsize);
926 1021
1022 if (sc->quirks & MOTION_CONTROLLER)
1023 return motion_fixup(hdev, rdesc, rsize);
1024
927 if (sc->quirks & PS3REMOTE) 1025 if (sc->quirks & PS3REMOTE)
928 return ps3remote_fixup(hdev, rdesc, rsize); 1026 return ps3remote_fixup(hdev, rdesc, rsize);
929 1027
@@ -1454,6 +1552,12 @@ static int sony_leds_init(struct sony_sc *sc)
1454 use_ds4_names = 1; 1552 use_ds4_names = 1;
1455 name_len = 0; 1553 name_len = 0;
1456 name_fmt = "%s:%s"; 1554 name_fmt = "%s:%s";
1555 } else if (sc->quirks & MOTION_CONTROLLER) {
1556 sc->led_count = 3;
1557 memset(max_brightness, 255, 3);
1558 use_ds4_names = 1;
1559 name_len = 0;
1560 name_fmt = "%s:%s";
1457 } else { 1561 } else {
1458 sixaxis_set_leds_from_id(sc->device_id, initial_values); 1562 sixaxis_set_leds_from_id(sc->device_id, initial_values);
1459 sc->led_count = 4; 1563 sc->led_count = 4;
@@ -1622,6 +1726,28 @@ static void dualshock4_state_worker(struct work_struct *work)
1622 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 1726 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
1623} 1727}
1624 1728
1729static void motion_state_worker(struct work_struct *work)
1730{
1731 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1732 struct hid_device *hdev = sc->hdev;
1733 struct motion_output_report_02 *report =
1734 (struct motion_output_report_02 *)sc->output_report_dmabuf;
1735
1736 memset(report, 0, sizeof(struct motion_output_report_02));
1737
1738 report->type = 0x02; /* set leds */
1739 report->r = sc->led_state[0];
1740 report->g = sc->led_state[1];
1741 report->b = sc->led_state[2];
1742
1743#ifdef CONFIG_SONY_FF
1744 report->rumble = max(sc->right, sc->left);
1745#endif
1746
1747 hid_hw_output_report(hdev, (__u8 *)report,
1748 sizeof(struct motion_output_report_02));
1749}
1750
1625static int sony_allocate_output_report(struct sony_sc *sc) 1751static int sony_allocate_output_report(struct sony_sc *sc)
1626{ 1752{
1627 if (sc->quirks & SIXAXIS_CONTROLLER) 1753 if (sc->quirks & SIXAXIS_CONTROLLER)
@@ -1634,6 +1760,10 @@ static int sony_allocate_output_report(struct sony_sc *sc)
1634 else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1760 else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1635 sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE, 1761 sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE,
1636 GFP_KERNEL); 1762 GFP_KERNEL);
1763 else if (sc->quirks & MOTION_CONTROLLER)
1764 sc->output_report_dmabuf =
1765 kmalloc(sizeof(struct motion_output_report_02),
1766 GFP_KERNEL);
1637 else 1767 else
1638 return 0; 1768 return 0;
1639 1769
@@ -2043,6 +2173,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
2043 } 2173 }
2044 2174
2045 sony_init_work(sc, dualshock4_state_worker); 2175 sony_init_work(sc, dualshock4_state_worker);
2176 } else if (sc->quirks & MOTION_CONTROLLER) {
2177 sony_init_work(sc, motion_state_worker);
2046 } else { 2178 } else {
2047 ret = 0; 2179 ret = 0;
2048 } 2180 }
@@ -2123,6 +2255,8 @@ static const struct hid_device_id sony_devices[] = {
2123 .driver_data = SIXAXIS_CONTROLLER_USB }, 2255 .driver_data = SIXAXIS_CONTROLLER_USB },
2124 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 2256 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
2125 .driver_data = SIXAXIS_CONTROLLER_USB }, 2257 .driver_data = SIXAXIS_CONTROLLER_USB },
2258 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
2259 .driver_data = MOTION_CONTROLLER },
2126 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2260 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2127 .driver_data = SIXAXIS_CONTROLLER_BT }, 2261 .driver_data = SIXAXIS_CONTROLLER_BT },
2128 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 2262 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),