aboutsummaryrefslogtreecommitdiff
path: root/hid-tmff2.c
diff options
context:
space:
mode:
Diffstat (limited to 'hid-tmff2.c')
-rw-r--r--hid-tmff2.c155
1 files changed, 104 insertions, 51 deletions
diff --git a/hid-tmff2.c b/hid-tmff2.c
index bb03df4..7b1a4f7 100644
--- a/hid-tmff2.c
+++ b/hid-tmff2.c
@@ -62,17 +62,28 @@ static unsigned int setup_arr_sizes[] = {
static u8 hw_rq_in[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 };
static u8 hw_rq_out[] = { 0x41, 0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static u8 ff_constant_array[] = {
+ 0x60, 0x00, 0x01, 0x0a, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
struct tmff_device {
struct hid_report *report;
struct hid_field *ff_field;
+ spinlock_t report_lock;
};
+static spinlock_t *report_lock;
+static int flags;
+
struct api_context {
struct completion done;
int status;
};
+static struct api_context ctx;
+
/* Changes values from 0 to 0xffff into values from minimum to maximum */
static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
{
@@ -99,71 +110,24 @@ static inline int tmff_scale_s8(int in, int minimum, int maximum)
return ret;
}
-static int tmff_play(struct input_dev *dev, void *data,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input_get_drvdata(dev);
- struct tmff_device *tmff = data;
- struct hid_field *ff_field = tmff->ff_field;
- int x, y;
- int left, right; /* Rumbling */
- int motor_swap;
-
- switch (effect->type) {
- case FF_CONSTANT:
- x = tmff_scale_s8(effect->u.ramp.start_level,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
- y = tmff_scale_s8(effect->u.ramp.end_level,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
-
- dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
- ff_field->value[0] = x;
- ff_field->value[1] = y;
- hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT);
- break;
-
- case FF_RUMBLE:
- left = tmff_scale_u16(effect->u.rumble.weak_magnitude,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
- right = tmff_scale_u16(effect->u.rumble.strong_magnitude,
- ff_field->logical_minimum,
- ff_field->logical_maximum);
-
- /* 2-in-1 strong motor is left */
- if (hid->product == THRUSTMASTER_DEVICE_ID_2_IN_1_DT) {
- motor_swap = left;
- left = right;
- right = motor_swap;
- }
-
- dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
- ff_field->value[0] = left;
- ff_field->value[1] = right;
- hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT);
- break;
- }
- return 0;
-}
-
static void tmff_ctrl(struct urb *urb){
if(urb->status){
hid_warn(urb->dev, "urb status %d received\n", urb->status);
}
+ usb_free_urb(urb);
+ spin_unlock_irqrestore(report_lock, flags);
}
static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
{
- struct api_context ctx;
+
unsigned long expire;
int retval;
init_completion(&ctx.done);
urb->context = &ctx;
urb->actual_length = 0;
- retval = usb_submit_urb(urb, GFP_NOIO);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(retval))
goto out;
@@ -189,6 +153,93 @@ out:
return retval;
}
+static int tmff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ spin_lock_irqsave(report_lock, flags);
+ printk("Reached debug point 1");
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct tmff_device *tmff = data;
+ struct hid_field *ff_field = tmff->ff_field;
+ int x, y;
+ int left, right; /* Rumbling */
+
+ printk("Reached debug point 2");
+ int trans, b_ep, err;
+ unsigned long flags;
+ struct device *d_dev = &hid->dev;
+ struct usb_interface *usbif = to_usb_interface(d_dev->parent);
+ struct usb_device *usbdev = interface_to_usbdev(usbif);
+ struct usb_host_endpoint *ep;
+
+ struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ printk("Reached debug point 3");
+ u8 *send_buf = kmalloc(1024, GFP_ATOMIC);
+ memcpy(send_buf, ff_constant_array, ARRAY_SIZE(ff_constant_array));
+
+ ep = &usbif->cur_altsetting->endpoint[1];
+ b_ep = ep->desc.bEndpointAddress;
+
+ printk("Reached debug point 4");
+ switch (effect->type) {
+ case FF_CONSTANT:
+
+ printk("Reached debug point 5");
+
+ x = tmff_scale_s8(effect->u.ramp.start_level,
+ ff_field->logical_minimum,
+ ff_field->logical_maximum);
+ y = tmff_scale_s8(effect->u.ramp.end_level,
+ ff_field->logical_minimum,
+ ff_field->logical_maximum);
+
+ printk("(x, y)=(%04x, %04x)\n", x, y);
+ //send_buf[4] = x;
+ //send_buf[5] = y;
+
+ printk("Reached debug point 6");
+
+ usb_fill_int_urb(
+ urb,
+ usbdev,
+ usb_sndintpipe(usbdev, 1),
+ send_buf,
+ ARRAY_SIZE(ff_constant_array),
+ tmff_ctrl,
+ hid,
+ ep->desc.bInterval
+ );
+
+ printk("Reached debug point yeet");
+ /*err = usb_start_wait_urb(urb, 1, &trans);
+ if(err){
+ hid_err(hid, "Failed sending thing with ERRNO: %i", err);
+ }*/
+ usb_submit_urb(urb, GFP_KERNEL);
+
+ printk("Reached debug point wooot");
+
+ /*usb_interrupt_msg(usbdev,
+ usb_sndintpipe(usbdev, b_ep),
+ send_buf,
+ ARRAY_SIZE(ff_constant_array),
+ &trans,
+ USB_CTRL_SET_TIMEOUT);*/
+
+ printk("Reached debug point 7");
+ break;
+ }
+ printk("Reached debug point X");
+ kfree(send_buf);
+ return 0;
+}
+
+static int tmff_init_t300rs(struct hid_device *hid){
+
+ return 0;
+}
+
static int tmff_clear_init(struct hid_device *hid){
/* die */
@@ -278,6 +329,8 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
if (!tmff)
return -ENOMEM;
+ spin_lock_init(&tmff->report_lock);
+ report_lock = &tmff->report_lock;
/* Find the report to use */
report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;