|
75 | 75 |
|
76 | 76 | #define MAX_LEDS 4
|
77 | 77 |
|
78 |
| -/* |
79 |
| - * The Sixaxis reports both digital and analog values for each button on the |
80 |
| - * controller except for Start, Select and the PS button. The controller ends |
81 |
| - * up reporting 27 axes which causes them to spill over into the multi-touch |
82 |
| - * axis values. Additionally, the controller only has 20 actual, physical axes |
83 |
| - * so there are several unused axes in between the used ones. |
84 |
| - */ |
85 |
| -static u8 sixaxis_rdesc[] = { |
86 |
| - 0x05, 0x01, /* Usage Page (Desktop), */ |
87 |
| - 0x09, 0x04, /* Usage (Joystick), */ |
88 |
| - 0xA1, 0x01, /* Collection (Application), */ |
89 |
| - 0xA1, 0x02, /* Collection (Logical), */ |
90 |
| - 0x85, 0x01, /* Report ID (1), */ |
91 |
| - 0x75, 0x08, /* Report Size (8), */ |
92 |
| - 0x95, 0x01, /* Report Count (1), */ |
93 |
| - 0x15, 0x00, /* Logical Minimum (0), */ |
94 |
| - 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ |
95 |
| - 0x81, 0x03, /* Input (Constant, Variable), */ |
96 |
| - 0x75, 0x01, /* Report Size (1), */ |
97 |
| - 0x95, 0x13, /* Report Count (19), */ |
98 |
| - 0x15, 0x00, /* Logical Minimum (0), */ |
99 |
| - 0x25, 0x01, /* Logical Maximum (1), */ |
100 |
| - 0x35, 0x00, /* Physical Minimum (0), */ |
101 |
| - 0x45, 0x01, /* Physical Maximum (1), */ |
102 |
| - 0x05, 0x09, /* Usage Page (Button), */ |
103 |
| - 0x19, 0x01, /* Usage Minimum (01h), */ |
104 |
| - 0x29, 0x13, /* Usage Maximum (13h), */ |
105 |
| - 0x81, 0x02, /* Input (Variable), */ |
106 |
| - 0x75, 0x01, /* Report Size (1), */ |
107 |
| - 0x95, 0x0D, /* Report Count (13), */ |
108 |
| - 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ |
109 |
| - 0x81, 0x03, /* Input (Constant, Variable), */ |
110 |
| - 0x15, 0x00, /* Logical Minimum (0), */ |
111 |
| - 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ |
112 |
| - 0x05, 0x01, /* Usage Page (Desktop), */ |
113 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
114 |
| - 0xA1, 0x00, /* Collection (Physical), */ |
115 |
| - 0x75, 0x08, /* Report Size (8), */ |
116 |
| - 0x95, 0x04, /* Report Count (4), */ |
117 |
| - 0x35, 0x00, /* Physical Minimum (0), */ |
118 |
| - 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ |
119 |
| - 0x09, 0x30, /* Usage (X), */ |
120 |
| - 0x09, 0x31, /* Usage (Y), */ |
121 |
| - 0x09, 0x32, /* Usage (Z), */ |
122 |
| - 0x09, 0x35, /* Usage (Rz), */ |
123 |
| - 0x81, 0x02, /* Input (Variable), */ |
124 |
| - 0xC0, /* End Collection, */ |
125 |
| - 0x05, 0x01, /* Usage Page (Desktop), */ |
126 |
| - 0x95, 0x13, /* Report Count (19), */ |
127 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
128 |
| - 0x81, 0x02, /* Input (Variable), */ |
129 |
| - 0x95, 0x0C, /* Report Count (12), */ |
130 |
| - 0x81, 0x01, /* Input (Constant), */ |
131 |
| - 0x75, 0x10, /* Report Size (16), */ |
132 |
| - 0x95, 0x04, /* Report Count (4), */ |
133 |
| - 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ |
134 |
| - 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ |
135 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
136 |
| - 0x81, 0x02, /* Input (Variable), */ |
137 |
| - 0xC0, /* End Collection, */ |
138 |
| - 0xA1, 0x02, /* Collection (Logical), */ |
139 |
| - 0x85, 0x02, /* Report ID (2), */ |
140 |
| - 0x75, 0x08, /* Report Size (8), */ |
141 |
| - 0x95, 0x30, /* Report Count (48), */ |
142 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
143 |
| - 0xB1, 0x02, /* Feature (Variable), */ |
144 |
| - 0xC0, /* End Collection, */ |
145 |
| - 0xA1, 0x02, /* Collection (Logical), */ |
146 |
| - 0x85, 0xEE, /* Report ID (238), */ |
147 |
| - 0x75, 0x08, /* Report Size (8), */ |
148 |
| - 0x95, 0x30, /* Report Count (48), */ |
149 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
150 |
| - 0xB1, 0x02, /* Feature (Variable), */ |
151 |
| - 0xC0, /* End Collection, */ |
152 |
| - 0xA1, 0x02, /* Collection (Logical), */ |
153 |
| - 0x85, 0xEF, /* Report ID (239), */ |
154 |
| - 0x75, 0x08, /* Report Size (8), */ |
155 |
| - 0x95, 0x30, /* Report Count (48), */ |
156 |
| - 0x09, 0x01, /* Usage (Pointer), */ |
157 |
| - 0xB1, 0x02, /* Feature (Variable), */ |
158 |
| - 0xC0, /* End Collection, */ |
159 |
| - 0xC0 /* End Collection */ |
160 |
| -}; |
161 | 78 |
|
162 | 79 | /* PS/3 Motion controller */
|
163 | 80 | static u8 motion_rdesc[] = {
|
@@ -508,6 +425,34 @@ static const unsigned int buzz_keymap[] = {
|
508 | 425 | [20] = BTN_TRIGGER_HAPPY20,
|
509 | 426 | };
|
510 | 427 |
|
| 428 | +static const unsigned int sixaxis_absmap[] = { |
| 429 | + [0x30] = ABS_X, |
| 430 | + [0x31] = ABS_Y, |
| 431 | + [0x32] = ABS_RX, /* right stick X */ |
| 432 | + [0x35] = ABS_RY, /* right stick Y */ |
| 433 | +}; |
| 434 | + |
| 435 | +static const unsigned int sixaxis_keymap[] = { |
| 436 | + [0x01] = BTN_SELECT, /* Select */ |
| 437 | + [0x02] = BTN_THUMBL, /* L3 */ |
| 438 | + [0x03] = BTN_THUMBR, /* R3 */ |
| 439 | + [0x04] = BTN_START, /* Start */ |
| 440 | + [0x05] = BTN_DPAD_UP, /* Up */ |
| 441 | + [0x06] = BTN_DPAD_RIGHT, /* Right */ |
| 442 | + [0x07] = BTN_DPAD_DOWN, /* Down */ |
| 443 | + [0x08] = BTN_DPAD_LEFT, /* Left */ |
| 444 | + [0x09] = BTN_TL2, /* L2 */ |
| 445 | + [0x0a] = BTN_TR2, /* R2 */ |
| 446 | + [0x0b] = BTN_TL, /* L1 */ |
| 447 | + [0x0c] = BTN_TR, /* R1 */ |
| 448 | + [0x0d] = BTN_NORTH, /* Triangle */ |
| 449 | + [0x0e] = BTN_EAST, /* Circle */ |
| 450 | + [0x0f] = BTN_SOUTH, /* Cross */ |
| 451 | + [0x10] = BTN_WEST, /* Square */ |
| 452 | + [0x11] = BTN_MODE, /* PS */ |
| 453 | +}; |
| 454 | + |
| 455 | + |
511 | 456 | static const unsigned int ds4_absmap[] = {
|
512 | 457 | [0x30] = ABS_X,
|
513 | 458 | [0x31] = ABS_Y,
|
@@ -695,13 +640,6 @@ static inline void sony_schedule_work(struct sony_sc *sc,
|
695 | 640 | }
|
696 | 641 | }
|
697 | 642 |
|
698 |
| -static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc, |
699 |
| - unsigned int *rsize) |
700 |
| -{ |
701 |
| - *rsize = sizeof(sixaxis_rdesc); |
702 |
| - return sixaxis_rdesc; |
703 |
| -} |
704 |
| - |
705 | 643 | static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
|
706 | 644 | unsigned int *rsize)
|
707 | 645 | {
|
@@ -757,6 +695,54 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
|
757 | 695 | return 1;
|
758 | 696 | }
|
759 | 697 |
|
| 698 | +static int sixaxis_mapping(struct hid_device *hdev, struct hid_input *hi, |
| 699 | + struct hid_field *field, struct hid_usage *usage, |
| 700 | + unsigned long **bit, int *max) |
| 701 | +{ |
| 702 | + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { |
| 703 | + unsigned int key = usage->hid & HID_USAGE; |
| 704 | + |
| 705 | + if (key >= ARRAY_SIZE(sixaxis_keymap)) |
| 706 | + return -1; |
| 707 | + |
| 708 | + key = sixaxis_keymap[key]; |
| 709 | + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); |
| 710 | + return 1; |
| 711 | + } else if (usage->hid == HID_GD_POINTER) { |
| 712 | + /* The DS3 provides analog values for most buttons and even |
| 713 | + * for HAT axes through GD Pointer. L2 and R2 are reported |
| 714 | + * among these as well instead of as GD Z / RZ. Remap L2 |
| 715 | + * and R2 and ignore other analog 'button axes' as there is |
| 716 | + * no good way for reporting them. |
| 717 | + */ |
| 718 | + switch (usage->usage_index) { |
| 719 | + case 8: /* L2 */ |
| 720 | + usage->hid = HID_GD_Z; |
| 721 | + break; |
| 722 | + case 9: /* R2 */ |
| 723 | + usage->hid = HID_GD_RZ; |
| 724 | + break; |
| 725 | + default: |
| 726 | + return -1; |
| 727 | + } |
| 728 | + |
| 729 | + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf); |
| 730 | + return 1; |
| 731 | + } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { |
| 732 | + unsigned int abs = usage->hid & HID_USAGE; |
| 733 | + |
| 734 | + if (abs >= ARRAY_SIZE(sixaxis_absmap)) |
| 735 | + return -1; |
| 736 | + |
| 737 | + abs = sixaxis_absmap[abs]; |
| 738 | + |
| 739 | + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); |
| 740 | + return 1; |
| 741 | + } |
| 742 | + |
| 743 | + return -1; |
| 744 | +} |
| 745 | + |
760 | 746 | static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi,
|
761 | 747 | struct hid_field *field, struct hid_usage *usage,
|
762 | 748 | unsigned long **bit, int *max)
|
@@ -812,9 +798,6 @@ static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
|
812 | 798 | rdesc[55] = 0x06;
|
813 | 799 | }
|
814 | 800 |
|
815 |
| - if (sc->quirks & SIXAXIS_CONTROLLER) |
816 |
| - return sixaxis_fixup(hdev, rdesc, rsize); |
817 |
| - |
818 | 801 | if (sc->quirks & MOTION_CONTROLLER)
|
819 | 802 | return motion_fixup(hdev, rdesc, rsize);
|
820 | 803 |
|
@@ -1196,10 +1179,13 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
|
1196 | 1179 | if (sc->quirks & PS3REMOTE)
|
1197 | 1180 | return ps3remote_mapping(hdev, hi, field, usage, bit, max);
|
1198 | 1181 |
|
| 1182 | + if (sc->quirks & SIXAXIS_CONTROLLER) |
| 1183 | + return sixaxis_mapping(hdev, hi, field, usage, bit, max); |
1199 | 1184 |
|
1200 | 1185 | if (sc->quirks & DUALSHOCK4_CONTROLLER)
|
1201 | 1186 | return ds4_mapping(hdev, hi, field, usage, bit, max);
|
1202 | 1187 |
|
| 1188 | + |
1203 | 1189 | /* Let hid-core decide for the others */
|
1204 | 1190 | return 0;
|
1205 | 1191 | }
|
@@ -2613,13 +2599,13 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
2613 | 2599 | else if (sc->quirks & SIXAXIS_CONTROLLER)
|
2614 | 2600 | connect_mask |= HID_CONNECT_HIDDEV_FORCE;
|
2615 | 2601 |
|
2616 |
| - /* Patch the hw version on DS4 compatible devices, so applications can |
| 2602 | + /* Patch the hw version on DS3/4 compatible devices, so applications can |
2617 | 2603 | * distinguish between the default HID mappings and the mappings defined
|
2618 | 2604 | * by the Linux game controller spec. This is important for the SDL2
|
2619 | 2605 | * library, which has a game controller database, which uses device ids
|
2620 | 2606 | * in combination with version as a key.
|
2621 | 2607 | */
|
2622 |
| - if (sc->quirks & DUALSHOCK4_CONTROLLER) |
| 2608 | + if (sc->quirks & (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)) |
2623 | 2609 | hdev->version |= 0x8000;
|
2624 | 2610 |
|
2625 | 2611 | ret = hid_hw_start(hdev, connect_mask);
|
|
0 commit comments