aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hid-tmt300rs.c36
-rw-r--r--hid-tmt300rs.h93
2 files changed, 116 insertions, 13 deletions
diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c
index b08e838..4bd8bc3 100644
--- a/hid-tmt300rs.c
+++ b/hid-tmt300rs.c
@@ -3,19 +3,23 @@
static int timer_msecs = DEFAULT_TIMER_PERIOD;
module_param(timer_msecs, int, 0660);
-MODULE_PARM_DESC(timer_msecs, "Timer resolution in msecs");
+MODULE_PARM_DESC(timer_msecs,
+ "Timer resolution in msecs");
static int spring_level = 30;
module_param(spring_level, int, 0);
-MODULE_PARM_DESC(spring_level, "Level of spring force (0-100), as per Oversteer standards");
+MODULE_PARM_DESC(spring_level,
+ "Level of spring force (0-100), as per Oversteer standards");
static int damper_level = 30;
module_param(damper_level, int, 0);
-MODULE_PARM_DESC(damper_level, "Level of damper force (0-100), as per Oversteer standards");
+MODULE_PARM_DESC(damper_level,
+ "Level of damper force (0-100), as per Oversteer standards");
static int friction_level = 30;
module_param(friction_level, int, 0);
-MODULE_PARM_DESC(friction_level, "Level of friction force (0-100), as per Oversteer standards");
+MODULE_PARM_DESC(friction_level,
+ "Level of friction force (0-100), as per Oversteer standards");
static struct t300rs_device_entry *t300rs_get_device(struct hid_device *hdev)
{
@@ -41,12 +45,12 @@ static struct t300rs_device_entry *t300rs_get_device(struct hid_device *hdev)
static int t300rs_send_int(struct t300rs_device_entry *t300rs)
{
int i;
- for (i = 0; i < T300RS_BUFFER_LENGTH; ++i)
+ for (i = 0; i < t300rs->buffer_length; ++i)
t300rs->ff_field->value[i] = t300rs->send_buffer[i];
hid_hw_request(t300rs->hdev, t300rs->report, HID_REQ_SET_REPORT);
- memset(t300rs->send_buffer, 0, T300RS_BUFFER_LENGTH);
+ memset(t300rs->send_buffer, 0, t300rs->buffer_length);
return 0;
}
@@ -1447,7 +1451,12 @@ static int t300rs_init(struct hid_device *hdev, const signed short *ff_bits)
goto states_err;
}
- t300rs->send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_KERNEL);
+ if(hdev->product == 0xb66d)
+ t300rs->buffer_length = T300RS_PS4_BUFFER_LENGTH;
+ else
+ t300rs->buffer_length = T300RS_NORM_BUFFER_LENGTH;
+
+ t300rs->send_buffer = kzalloc(t300rs->buffer_length, GFP_KERNEL);
if (!t300rs->send_buffer) {
ret = -ENOMEM;
goto send_err;
@@ -1627,12 +1636,19 @@ static void t300rs_remove(struct hid_device *hdev)
kfree(drv_data);
}
-static __u8 *t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize)
+static __u8 *t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
{
if(hdev->product == 0xb66e) {
+ /* PS3 normal mode */
rdesc = t300rs_rdesc_nrm_fixed;
*rsize = sizeof(t300rs_rdesc_nrm_fixed);
- } else {
+ } else if (hdev->product == 0xb66d){
+ /* PS4 normal mode */
+ rdesc = t300rs_rdesc_ps4_fixed;
+ *rsize = sizeof(t300rs_rdesc_ps4_fixed);
+ } else if (hdev->product == 0xb66f){
+ /* PS3 advanced mode */
rdesc = t300rs_rdesc_adv_fixed;
*rsize = sizeof(t300rs_rdesc_adv_fixed);
}
@@ -1645,6 +1661,8 @@ static const struct hid_device_id t300rs_devices[] = {
.driver_data = (unsigned long)t300rs_ff_effects},
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66f),
.driver_data = (unsigned long)t300rs_ff_effects},
+ {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66d),
+ .driver_data = (unsigned long)t300rs_ff_effects},
{}
};
MODULE_DEVICE_TABLE(hid, t300rs_devices);
diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h
index 9ffd87c..3c3a3a9 100644
--- a/hid-tmt300rs.h
+++ b/hid-tmt300rs.h
@@ -13,7 +13,8 @@
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
#define T300RS_MAX_EFFECTS 16
-#define T300RS_BUFFER_LENGTH 63
+#define T300RS_NORM_BUFFER_LENGTH 63
+#define T300RS_PS4_BUFFER_LENGTH 31
/* the wheel seems to only be capable of processing a certain number of
* interrupts per second, and if this value is too low the kernel urb buffer(or
@@ -126,6 +127,7 @@ struct t300rs_device_entry {
spinlock_t lock;
unsigned long lock_flags;
+ u8 buffer_length;
u8 *send_buffer;
u16 range;
@@ -140,7 +142,7 @@ struct t300rs_data {
void *device_props;
};
-static __u8 t300rs_rdesc_nrm_fixed[] = {
+static u8 t300rs_rdesc_nrm_fixed[] = {
0x05, 0x01, /* Usage page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */
0xa1, 0x01, /* Collection (Application) */
@@ -205,7 +207,7 @@ static __u8 t300rs_rdesc_nrm_fixed[] = {
0xc0, /* End collection */
};
-static __u8 t300rs_rdesc_adv_fixed[] = {
+static u8 t300rs_rdesc_adv_fixed[] = {
0x05, 0x01, /* Usage page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */
0xa1, 0x01, /* Collection (Application) */
@@ -243,7 +245,7 @@ static __u8 t300rs_rdesc_adv_fixed[] = {
0x05, 0x01, /* Usage page (Generic Desktop) */
0x09, 0x39, /* Usage (Hat Switch) */
0x25, 0x07, /* Logical maximum (7) */
- 0x46, 0x3b, 0x01, /* Physical maximum (315) */
+ 0x46, 0x3b, 0x01, /* Physical maximum (315) */
0x55, 0x00, /* Unit exponent (0) */
0x65, 0x14, /* Unit (Eng Rot, Angular Pos) */
0x75, 0x04, /* Report size (4) */
@@ -267,6 +269,89 @@ static __u8 t300rs_rdesc_adv_fixed[] = {
0xc0, /* End collection */
};
+static u8 t300rs_rdesc_ps4_fixed[] = {
+ 0x05, 0x01, /* Usage page (Generic Desktop) */
+ 0x09, 0x05, /* Usage (GamePad) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x01, /* Report ID (1) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x09, 0x32, /* Usage (Z) */
+ 0x09, 0x35, /* Usage (Rz) */
+ 0x15, 0x00, /* Logical minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical maximum (255) */
+ 0x75, 0x08, /* Report size (8) */
+ 0x95, 0x04, /* Report count (4) */
+ 0x81, 0x02, /* Input (Variable, Absolute) */
+ 0x09, 0x39, /* Usage (Hat Switch) */
+ 0x15, 0x00, /* Logical minimum (0) */
+ 0x25, 0x07, /* Logical maximum (7)*/
+ 0x35, 0x00, /* Physical minimum (0) */
+ 0x46, 0x3b, 0x01, /* Physical maximum (315) */
+ 0x65, 0x14, /* Unit (Eng Rot, Angular Pos) */
+ 0x75, 0x04, /* Report size (4) */
+ 0x95, 0x01, /* Report count (1) */
+ 0x81, 0x42, /* Input (Variable, Absolute, NullState) */
+ 0x65, 0x00, /* Input (None) */
+ 0x05, 0x09, /* Usage page (Button) */
+ 0x19, 0x01, /* Usage minimum (1) */
+ 0x29, 0x0e, /* Usage maximum (14) */
+ 0x15, 0x00, /* Logical minimum (0) */
+ 0x25, 0x01, /* Logical maximum (1) */
+ 0x75, 0x01, /* Report size (1) */
+ 0x95, 0x0e, /* Report size (14) */
+ 0x81, 0x02, /* Input (Variable, Absolute) */
+ 0x06, 0x00, 0xff, /* Usage page (Vendor 1) */
+ 0x09, 0x20, /* Usage (32) */
+ 0x75, 0x06, /* Report size (6) */
+ 0x95, 0x01, /* Report count (1) */
+ 0x81, 0x02, /* Input (Variable, Absolute) */
+ 0x05, 0x01, /* Usage page (Generic Desktop) */
+ 0x09, 0x33, /* Usage (Rx) */
+ 0x09, 0x34, /* Usage (Ry) */
+ 0x15, 0x00, /* Logical minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical maximum (255) */
+ 0x75, 0x08, /* Report size (8) */
+ 0x95, 0x02, /* Report count (2) */
+ 0x81, 0x02, /* Input (Variable, Absolute) */
+ 0x06, 0x00, 0xff, /* Usage page (Vendor 1) */
+ 0x09, 0x21, /* Usage (33) */
+ 0x95, 0x36, /* Report count (54) */
+ 0x81, 0x02, /* Input (Variable, Absolute) */
+ 0x85, 0x60, /* Report ID (5) (change to 0x60?) */
+ 0x09, 0x60, /* Usage (34) (change to 0x60?) */
+ 0x95, 0x1f, /* Report count (31) () */
+ 0x91, 0x02, /* Output (Variable, Absolute) */
+ 0x85, 0x03, /* Report ID (3) */
+ 0x0a, 0x21, 0x27, /* ??? */
+ 0x95, 0x2f, /* Report count (47) */
+ 0xb1, 0x02, /* Feature (Data, Var, Abs) */
+ 0xc0, /* End collection */
+
+ /* From here on out no clue */
+ 0x06, 0xf0,
+ 0xff, 0x09,
+ 0x40, 0xa1,
+ 0x01, 0x85,
+ 0xf0, 0x09,
+ 0x47, 0x95,
+ 0x3f, 0xb1,
+ 0x02, 0x85,
+ 0xf1, 0x09,
+ 0x48, 0x95,
+ 0x3f, 0xb1,
+ 0x02, 0x85,
+ 0xf2, 0x09,
+ 0x49, 0x95,
+ 0x0f, 0xb1,
+ 0x02, 0x85,
+ 0xf3, 0x0a,
+ 0x01, 0x47,
+ 0x95, 0x07,
+ 0xb1, 0x02,
+ 0xc0,
+};
+
static u8 spring_values[] = {
0xa6, 0x6a, 0xa6, 0x6a, 0xfe,
0xff, 0xfe, 0xff, 0xfe, 0xff,