diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-03-24 20:48:04 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-03-24 20:48:04 +0200 |
| commit | 301f7fa87fa2bafbd9ed3436aa7eb865b341563c (patch) | |
| tree | 1bda82c0cd2f0093d74fb423da626fde0f17dd0a | |
| parent | c2be549438657a7e0b863a1ed58ba17e8fb5ff33 (diff) | |
| download | hid-tmff2-301f7fa87fa2bafbd9ed3436aa7eb865b341563c.tar.gz hid-tmff2-301f7fa87fa2bafbd9ed3436aa7eb865b341563c.zip | |
Merge branch 'minalloc'
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | Makefile | 20 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | hid-tm.h | 48 | ||||
| m--------- | hid-tminit | 0 | ||||
| -rw-r--r-- | hid-tminit.c | 131 | ||||
| -rw-r--r-- | hid-tminit.h | 18 | ||||
| -rw-r--r-- | hid-tmt300rs.c | 2216 | ||||
| -rw-r--r-- | hid-tmt300rs.h | 148 | ||||
| -rw-r--r-- | usbhid.h | 95 |
10 files changed, 1241 insertions, 1440 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9415bdf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "hid-tminit"] + path = hid-tminit + url = https://github.com/scarburato/hid-tminit.git @@ -1,11 +1,17 @@ -obj-m += hid-tminit.o obj-m += hid-tmt300rs.o +KDIR ?= /lib/modules/$(shell uname -r)/build -all: - make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules -install: - make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules_install +all: hid-tminit + $(MAKE) -C $(KDIR) M=$(shell pwd) modules + +install: hid-tminit + $(MAKE) -C $(KDIR) M=$(shell pwd) modules_install depmod -A -clean: - make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean +clean: hid-tminit + $(MAKE) -C $(KDIR) M=$(shell pwd) clean + + +.PHONY: hid-tminit +hid-tminit: + $(MAKE) -C hid-tminit $(MAKECMDGOALS) @@ -18,7 +18,7 @@ With that in mind, ## Installation + Unplug wheel from computer -+ `git clone https://github.com/Kimplul/hid-tmff2.git` ++ `git clone --recurse-submodules https://github.com/Kimplul/hid-tmff2.git` + `make` + `sudo make install` + Plug wheel back in diff --git a/hid-tm.h b/hid-tm.h deleted file mode 100644 index e0117ae..0000000 --- a/hid-tm.h +++ /dev/null @@ -1,48 +0,0 @@ -#include <linux/hid.h> -#include <linux/usb.h> -#include <linux/input.h> -#include <linux/slab.h> -#include <linux/module.h> - -#define USB_VENDOR_ID_THRUSTMASTER 0x044f - -struct api_context { - struct completion done; - int status; -}; - -struct api_context ctx; - -int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) -{ - unsigned long expire; - int retval; - - init_completion(&ctx.done); - urb->context = &ctx; - urb->actual_length = 0; - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(retval)) - goto out; - - expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&ctx.done, expire)) { - usb_kill_urb(urb); - retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); - - dev_dbg(&urb->dev->dev, - "%s timed out on ep%d%s len=%u/%u\n", - current->comm, - usb_endpoint_num(&urb->ep->desc), - usb_urb_dir_in(urb) ? "in" : "out", - urb->actual_length, - urb->transfer_buffer_length); - } else - retval = ctx.status; -out: - if (actual_length) - *actual_length = urb->actual_length; - - usb_free_urb(urb); - return retval; -} diff --git a/hid-tminit b/hid-tminit new file mode 160000 +Subproject 8b9802ac40ade7a09c6bc52298e3501cfdc0732 diff --git a/hid-tminit.c b/hid-tminit.c deleted file mode 100644 index b4b7b90..0000000 --- a/hid-tminit.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "hid-tminit.h" - -static void tminit_callback(struct urb *urb){ - if(urb->status){ - hid_info(urb->dev, "urb status %d received\n", urb->status); - } - - usb_free_urb(urb); -} - -/* for some godawful reason these interrupts are absolutely necessary, otherwise - * the whole kernel crashes. I have no idea why. - * */ -static void tminit_interrupts(struct hid_device *hdev){ - int ret, trans, i, b_ep; - u8 *send_buf = kmalloc(256, GFP_KERNEL); - - struct usb_host_endpoint *ep; - struct device *dev = &hdev->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - - ep = &usbif->cur_altsetting->endpoint[1]; - b_ep = ep->desc.bEndpointAddress; - - for(i = 0; i < ARRAY_SIZE(setup_arr); ++i){ - memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]); - - ret = usb_interrupt_msg(usbdev, - usb_sndintpipe(usbdev, b_ep), - send_buf, - setup_arr_sizes[i], - &trans, - USB_CTRL_SET_TIMEOUT - ); - - if(ret){ - hid_err(hdev, "setup data couldn't be sent\n"); - return; - } - - } - - kfree(send_buf); -} - -int tminit(struct hid_device *hdev){ - struct urb *urb; - u8 *setup_packet, *transfer_buffer; - struct device *dev = &hdev->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - int ret; - u8 *transfer = kzalloc(64, GFP_ATOMIC); - - tminit_interrupts(hdev); - - setup_packet = kmalloc(8, GFP_ATOMIC); - transfer_buffer = kmalloc(8, GFP_ATOMIC); - - memcpy(setup_packet, hw_rq_out, 8); - memcpy(transfer_buffer, hw_rq_in, 8); - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - usb_fill_control_urb(urb, - usbdev, - usb_sndctrlpipe(usbdev, 0), - setup_packet, - transfer_buffer, - 8, - tminit_callback, - hdev); - - /* we sort of have to go on faith that the message is sent, because the - * wheel usually completely dies as soon as it receives the message. - * No need to even check the return value. - */ - ret = usb_submit_urb(urb, GFP_ATOMIC); - kfree(setup_packet); - kfree(transfer_buffer); - kfree(transfer); - return ret; -} - -static void tminit_remove(struct hid_device *hdev){ - /* we are dead, hopefully without any serious side effects */ - hid_hw_stop(hdev); -} - -static int tminit_probe(struct hid_device *hdev, const struct hid_device_id *id){ - int ret; - - ret = hid_parse(hdev); - if(ret){ - hid_err(hdev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if(ret){ - hid_err(hdev, "hw start failed\n"); - goto err; - } - - ret = tminit(hdev); - if(ret){ - hid_err(hdev, "tminit exited, error might be intended behaviour\n"); - goto err; - } - -err: - return ret; -} - -static const struct hid_device_id tminit_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65d)}, - {} -}; - -MODULE_DEVICE_TABLE(hid, tminit_devices); - -static struct hid_driver tminit_driver = { - .name = "thrustmaster init", - .id_table = tminit_devices, - .probe = tminit_probe, - .remove = tminit_remove, -}; -module_hid_driver(tminit_driver); - -MODULE_LICENSE("GPL"); diff --git a/hid-tminit.h b/hid-tminit.h deleted file mode 100644 index cd12f9b..0000000 --- a/hid-tminit.h +++ /dev/null @@ -1,18 +0,0 @@ -#include "hid-tm.h" - -u8 hw_rq_in[] = { 0xc1, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }; -u8 hw_rq_out[] = { 0x41, 0x53, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -u8 setup_0[] = { 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -u8 setup_1[] = { 0x0a, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00 }; -u8 setup_2[] = { 0x0a, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00 }; -u8 setup_3[] = { 0x0a, 0x04, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00 }; -u8 setup_4[] = { 0x0a, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 }; -u8 *setup_arr[] = { setup_0, setup_1, setup_2, setup_3, setup_4 }; -unsigned int setup_arr_sizes[] = { - ARRAY_SIZE(setup_0), - ARRAY_SIZE(setup_1), - ARRAY_SIZE(setup_2), - ARRAY_SIZE(setup_3), - ARRAY_SIZE(setup_4) -}; diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index a7fd0c1..6abe149 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -18,1511 +18,1541 @@ MODULE_PARM_DESC(friction_level, "Level of friction force (0-100), as per Overst static struct t300rs_device_entry *t300rs_get_device(struct hid_device *hdev){ - struct t300rs_data *drv_data; - struct t300rs_device_entry *t300rs; + struct t300rs_data *drv_data; + struct t300rs_device_entry *t300rs; - spin_lock_irqsave(&lock, lock_flags); - drv_data = hid_get_drvdata(hdev); - if(!drv_data){ - hid_err(hdev, "private data not found\n"); - return NULL; - } + spin_lock_irqsave(&lock, lock_flags); + drv_data = hid_get_drvdata(hdev); + if(!drv_data){ + hid_err(hdev, "private data not found\n"); + return NULL; + } - t300rs = drv_data->device_props; - if(!t300rs){ - hid_err(hdev, "device properties not found\n"); - return NULL; - } - spin_unlock_irqrestore(&lock, lock_flags); - return t300rs; + t300rs = drv_data->device_props; + if(!t300rs){ + hid_err(hdev, "device properties not found\n"); + return NULL; + } + spin_unlock_irqrestore(&lock, lock_flags); + return t300rs; } static int t300rs_send_int(struct input_dev *dev, u8 *send_buffer, int *trans){ - struct hid_device *hdev = input_get_drvdata(dev); - struct t300rs_device_entry *t300rs; - int i; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + int i; - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - for(i = 0; i < T300RS_BUFFER_LENGTH; ++i){ - t300rs->ff_field->value[i] = send_buffer[i]; - } + for(i = 0; i < T300RS_BUFFER_LENGTH; ++i){ + t300rs->ff_field->value[i] = send_buffer[i]; + } - hid_hw_request(t300rs->hdev, t300rs->report, HID_REQ_SET_REPORT); + hid_hw_request(t300rs->hdev, t300rs->report, HID_REQ_SET_REPORT); - return 0; + memset(send_buffer, 0, T300RS_BUFFER_LENGTH); + + return 0; } static int t300rs_play_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - int ret, trans; + u8 *send_buffer = t300rs->send_buffer; + int ret, trans; + + + send_buffer[1] = state->effect.id + 1; + send_buffer[2] = 0x89; + send_buffer[3] = 0x01; - - send_buffer[1] = state->effect.id + 1; - send_buffer[2] = 0x89; - send_buffer[3] = 0x01; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed starting effect play\n"); + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed starting effect play\n"); - } - kfree(send_buffer); - return ret; + return ret; } static int t300rs_stop_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - int ret, trans; + u8 *send_buffer = t300rs->send_buffer; + int ret, trans; + + + send_buffer[1] = state->effect.id + 1; + send_buffer[2] = 0x89; - - send_buffer[1] = state->effect.id + 1; - send_buffer[2] = 0x89; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed stopping effect play\n"); + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed stopping effect play\n"); - } - kfree(send_buffer); - return ret; + return ret; } static void t300rs_fill_envelope(u8 *send_buffer, int i, s16 level, u16 duration, struct ff_envelope *envelope){ - u16 attack_length = (duration * envelope->attack_length) / 0x7fff; - u16 attack_level = (level * envelope->attack_level) / 0x7fff; - u16 fade_length = (duration * envelope->fade_length) / 0x7fff; - u16 fade_level = (level * envelope->fade_level) / 0x7fff; + u16 attack_length = (duration * envelope->attack_length) / 0x7fff; + u16 attack_level = (level * envelope->attack_level) / 0x7fff; + u16 fade_length = (duration * envelope->fade_length) / 0x7fff; + u16 fade_level = (level * envelope->fade_level) / 0x7fff; - send_buffer[i ] = attack_length & 0xff; - send_buffer[i + 1] = attack_length >> 8; - send_buffer[i + 2] = attack_level & 0xff; - send_buffer[i + 3] = attack_level >> 8; - send_buffer[i + 4] = fade_length & 0xff; - send_buffer[i + 5] = fade_length >> 8; - send_buffer[i + 6] = fade_level & 0xff; - send_buffer[i + 7] = fade_level >> 8; + send_buffer[i ] = attack_length & 0xff; + send_buffer[i + 1] = attack_length >> 8; + send_buffer[i + 2] = attack_level & 0xff; + send_buffer[i + 3] = attack_level >> 8; + send_buffer[i + 4] = fade_length & 0xff; + send_buffer[i + 5] = fade_length >> 8; + send_buffer[i + 6] = fade_level & 0xff; + send_buffer[i + 7] = fade_level >> 8; } static int t300rs_modify_envelope(struct t300rs_device_entry *t300rs, - struct t300rs_effect_state *state, - u8 *send_buffer, - s16 level, - u16 duration, - u8 id, - struct ff_envelope envelope, - struct ff_envelope envelope_old - ){ - u16 attack_length, attack_level, fade_length, fade_level; - int ret = 0, trans; + struct t300rs_effect_state *state, + u8 *send_buffer, + s16 level, + u16 duration, + u8 id, + struct ff_envelope envelope, + struct ff_envelope envelope_old + ){ + u16 attack_length, attack_level, fade_length, fade_level; + int ret = 0, trans; - if(duration == 0){ - duration = 0xffff; - } + if(duration == 0){ + duration = 0xffff; + } - attack_length = (duration * envelope.attack_length) / 0x7fff; - attack_level = (level * envelope.attack_level) / 0x7fff; - fade_length = (duration * envelope.fade_length) / 0x7fff; - fade_level = (level * envelope.fade_level) / 0x7fff; + attack_length = (duration * envelope.attack_length) / 0x7fff; + attack_level = (level * envelope.attack_level) / 0x7fff; + fade_length = (duration * envelope.fade_length) / 0x7fff; + fade_level = (level * envelope.fade_level) / 0x7fff; - - send_buffer[1] = id + 1; - send_buffer[2] = 0x31; - if(envelope.attack_length != envelope_old.attack_length){ - send_buffer[3] = 0x81; + send_buffer[1] = id + 1; + send_buffer[2] = 0x31; - send_buffer[4] = attack_length & 0xff; - send_buffer[5] = attack_length >> 8; + if(envelope.attack_length != envelope_old.attack_length){ + send_buffer[3] = 0x81; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying effect envelope\n"); - goto error; - } - } + send_buffer[4] = attack_length & 0xff; + send_buffer[5] = attack_length >> 8; - if(envelope.attack_level != envelope_old.attack_level){ - send_buffer[3] = 0x82; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying effect envelope\n"); + goto error; + } + } - send_buffer[4] = attack_level & 0xff; - send_buffer[5] = attack_level >> 8; + if(envelope.attack_level != envelope_old.attack_level){ + send_buffer[3] = 0x82; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying effect envelope\n"); - goto error; - } - } + send_buffer[4] = attack_level & 0xff; + send_buffer[5] = attack_level >> 8; - if(envelope.fade_length != envelope_old.fade_length){ - send_buffer[3] = 0x84; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying effect envelope\n"); + goto error; + } + } - send_buffer[4] = fade_length & 0xff; - send_buffer[5] = fade_length >> 8; + if(envelope.fade_length != envelope_old.fade_length){ + send_buffer[3] = 0x84; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying effect envelope\n"); - goto error; - } - } + send_buffer[4] = fade_length & 0xff; + send_buffer[5] = fade_length >> 8; - if(envelope.fade_level != envelope_old.fade_level){ - send_buffer[3] = 0x88; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying effect envelope\n"); + goto error; + } + } - send_buffer[4] = fade_level & 0xff; - send_buffer[5] = fade_level >> 8; + if(envelope.fade_level != envelope_old.fade_level){ + send_buffer[3] = 0x88; + + send_buffer[4] = fade_level & 0xff; + send_buffer[5] = fade_level >> 8; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying effect envelope\n"); + goto error; + } + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying effect envelope\n"); - goto error; - } - } - error: - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - return ret; + return ret; } static int t300rs_modify_duration(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state, u8 *send_buffer){ - struct ff_effect effect = state->effect; - struct ff_effect old = state->old; - u16 duration; - int ret = 0, trans; - - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } + struct ff_effect effect = state->effect; + struct ff_effect old = state->old; + u16 duration; + int ret = 0, trans; + + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } + + if(effect.replay.length != old.replay.length){ - if(effect.replay.length != old.replay.length){ - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x49; - send_buffer[4] = 0x41; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x49; + send_buffer[4] = 0x41; - send_buffer[5] = duration & 0xff; - send_buffer[6] = duration >> 8; + send_buffer[5] = duration & 0xff; + send_buffer[6] = duration >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying duration\n"); - goto error; - } - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying duration\n"); + goto error; + } + } error: - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - return ret; + return ret; } static int t300rs_modify_constant(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state, u8 *send_buffer){ - struct ff_effect effect = state->effect; - struct ff_effect old = state->old; - struct ff_constant_effect constant = effect.u.constant; - struct ff_constant_effect constant_old = old.u.constant; - int ret, trans; - s16 level; + struct ff_effect effect = state->effect; + struct ff_effect old = state->old; + struct ff_constant_effect constant = effect.u.constant; + struct ff_constant_effect constant_old = old.u.constant; + int ret, trans; + s16 level; - level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - if(constant.level != constant_old.level){ - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0a; + if(constant.level != constant_old.level){ - send_buffer[3] = level & 0xff; - send_buffer[4] = level >> 8; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0a; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying constant effect\n"); - goto error; - } + send_buffer[3] = level & 0xff; + send_buffer[4] = level >> 8; - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying constant effect\n"); + goto error; + } - ret = t300rs_modify_envelope(t300rs, - state, - send_buffer, - level, - effect.replay.length, - effect.id, - constant.envelope, - constant_old.envelope - ); - if(ret){ - hid_err(t300rs->hdev, "failed modifying constant envelope\n"); - goto error; - } + } - ret = t300rs_modify_duration(t300rs, state, send_buffer); - if(ret){ - hid_err(t300rs->hdev, "failed modifying constant duration\n"); - goto error; - } + ret = t300rs_modify_envelope(t300rs, + state, + send_buffer, + level, + effect.replay.length, + effect.id, + constant.envelope, + constant_old.envelope + ); + if(ret){ + hid_err(t300rs->hdev, "failed modifying constant envelope\n"); + goto error; + } + + ret = t300rs_modify_duration(t300rs, state, send_buffer); + if(ret){ + hid_err(t300rs->hdev, "failed modifying constant duration\n"); + goto error; + } error: - kfree(send_buffer); - return ret; + + return ret; } static int t300rs_modify_ramp(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state, u8 *send_buffer){ - struct ff_effect effect = state->effect; - struct ff_effect old = state->old; - struct ff_ramp_effect ramp = effect.u.ramp; - struct ff_ramp_effect ramp_old = old.u.ramp; - int ret, trans; + struct ff_effect effect = state->effect; + struct ff_effect old = state->old; + struct ff_ramp_effect ramp = effect.u.ramp; + struct ff_ramp_effect ramp_old = old.u.ramp; + int ret, trans; - u16 difference, top, bottom; - s16 level; + u16 difference, top, bottom; + s16 level; - top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; - bottom = ramp.end_level > ramp.start_level ? ramp.start_level : ramp.end_level; + top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; + bottom = ramp.end_level > ramp.start_level ? ramp.start_level : ramp.end_level; - difference = ((top - bottom) * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + difference = ((top - bottom) * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - level = (top * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + level = (top * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - if(ramp.start_level != ramp_old.start_level || ramp.end_level != ramp_old.end_level){ + if(ramp.start_level != ramp_old.start_level || ramp.end_level != ramp_old.end_level){ - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x03; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x03; - send_buffer[4] = difference & 0xff; - send_buffer[5] = difference >> 8; + send_buffer[4] = difference & 0xff; + send_buffer[5] = difference >> 8; - send_buffer[6] = level & 0xff; - send_buffer[7] = level >> 8; + send_buffer[6] = level & 0xff; + send_buffer[7] = level >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying ramp effect\n"); - goto error; - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying ramp effect\n"); + goto error; + } - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + } - ret = t300rs_modify_envelope(t300rs, - state, - send_buffer, - level, - effect.replay.length, - effect.id, - ramp.envelope, - ramp_old.envelope - ); + ret = t300rs_modify_envelope(t300rs, + state, + send_buffer, + level, + effect.replay.length, + effect.id, + ramp.envelope, + ramp_old.envelope + ); - if(ret){ - hid_err(t300rs->hdev, "failed modifying ramp envelope\n"); - goto error; - } + if(ret){ + hid_err(t300rs->hdev, "failed modifying ramp envelope\n"); + goto error; + } - ret = t300rs_modify_duration(t300rs, state, send_buffer); - if(ret){ - hid_err(t300rs->hdev, "failed modifying ramp duration\n"); - goto error; - } + ret = t300rs_modify_duration(t300rs, state, send_buffer); + if(ret){ + hid_err(t300rs->hdev, "failed modifying ramp duration\n"); + goto error; + } error: - kfree(send_buffer); - return ret; + + return ret; } static int t300rs_modify_damper(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state, u8 *send_buffer){ - struct ff_effect effect = state->effect; - struct ff_effect old = state->old; - struct ff_condition_effect damper = effect.u.condition[0]; - struct ff_condition_effect damper_old = old.u.condition[0]; - int ret, trans, input_level; + struct ff_effect effect = state->effect; + struct ff_effect old = state->old; + struct ff_condition_effect damper = effect.u.condition[0]; + struct ff_condition_effect damper_old = old.u.condition[0]; + int ret, trans, input_level; + + input_level = damper_level; + if(state->effect.type == FF_FRICTION) + input_level = friction_level; + + if(state->effect.type == FF_SPRING) + input_level = spring_level; - input_level = damper_level; - if(state->effect.type == FF_FRICTION) - input_level = friction_level; + if(damper.right_coeff != damper_old.right_coeff){ + s16 coeff = damper.right_coeff * input_level / 100; - if(state->effect.type == FF_SPRING) - input_level = spring_level; - if(damper.right_coeff != damper_old.right_coeff){ - s16 coeff = damper.right_coeff * input_level / 100; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x41; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x41; + send_buffer[4] = coeff & 0xff; + send_buffer[5] = coeff >> 8; - send_buffer[4] = coeff & 0xff; - send_buffer[5] = coeff >> 8; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying damper rc\n"); + goto error; + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying damper rc\n"); - goto error; - } + } - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + if(damper.left_coeff != damper_old.left_coeff){ + s16 coeff = damper.left_coeff * input_level / 100; - if(damper.left_coeff != damper_old.left_coeff){ - s16 coeff = damper.left_coeff * input_level / 100; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x42; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x42; - send_buffer[4] = coeff & 0xff; - send_buffer[5] = coeff >> 8; + send_buffer[4] = coeff & 0xff; + send_buffer[5] = coeff >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying damper lc\n"); - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying damper lc\n"); + } - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } - - if((damper.deadband != damper_old.deadband) || - (damper.center != damper_old.center)){ - u16 deadband_right = 0xfffe - damper.deadband - damper.center; - u16 deadband_left = 0xfffe - damper.deadband + damper.center; - - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x4c; + } - send_buffer[4] = deadband_right & 0xff; - send_buffer[5] = deadband_right >> 8; + if((damper.deadband != damper_old.deadband) || + (damper.center != damper_old.center)){ + u16 deadband_right = 0xfffe - damper.deadband - damper.center; + u16 deadband_left = 0xfffe - damper.deadband + damper.center; - send_buffer[6] = deadband_left & 0xff; - send_buffer[7] = deadband_left >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying damper deadband\n"); - } + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x4c; - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + send_buffer[4] = deadband_right & 0xff; + send_buffer[5] = deadband_right >> 8; - ret = t300rs_modify_duration(t300rs, state, send_buffer); - if(ret){ - hid_err(t300rs->hdev, "failed modifying damper duration\n"); - goto error; - } + send_buffer[6] = deadband_left & 0xff; + send_buffer[7] = deadband_left >> 8; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying damper deadband\n"); + } + + } + + ret = t300rs_modify_duration(t300rs, state, send_buffer); + if(ret){ + hid_err(t300rs->hdev, "failed modifying damper duration\n"); + goto error; + } error: - kfree(send_buffer); - return ret; + + return ret; } static int t300rs_modify_periodic(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state, u8 *send_buffer){ - struct ff_effect effect = state->effect; - struct ff_effect old = state->old; - struct ff_periodic_effect periodic = effect.u.periodic; - struct ff_periodic_effect periodic_old = old.u.periodic; - int ret, trans; - s16 level; + struct ff_effect effect = state->effect; + struct ff_effect old = state->old; + struct ff_periodic_effect periodic = effect.u.periodic; + struct ff_periodic_effect periodic_old = old.u.periodic; + int ret, trans; + s16 level; - level = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + level = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - if(periodic.magnitude != periodic_old.magnitude){ - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x01; + if(periodic.magnitude != periodic_old.magnitude){ - send_buffer[4] = level & 0xff; - send_buffer[5] = level >> 8; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x01; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic magnitude\n"); - goto error; - } + send_buffer[4] = level & 0xff; + send_buffer[5] = level >> 8; - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic magnitude\n"); + goto error; + } - if(periodic.offset != periodic_old.offset){ - s16 offset = periodic.offset; + } - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x02; + if(periodic.offset != periodic_old.offset){ + s16 offset = periodic.offset; - send_buffer[4] = offset & 0xff; - send_buffer[5] = offset >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic offset\n"); - } + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x02; - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } - - if(periodic.phase != periodic_old.phase){ - s16 phase = periodic.phase; + send_buffer[4] = offset & 0xff; + send_buffer[5] = offset >> 8; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x04; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic offset\n"); + } - send_buffer[4] = phase & 0xff; - send_buffer[5] = phase >> 8; + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic phase\n"); - } + if(periodic.phase != periodic_old.phase){ + s16 phase = periodic.phase; - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } - if(periodic.period != periodic_old.period){ - s16 period = periodic.period; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x04; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x0e; - send_buffer[3] = 0x08; + send_buffer[4] = phase & 0xff; + send_buffer[5] = phase >> 8; - send_buffer[4] = period & 0xff; - send_buffer[5] = period >> 8; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic phase\n"); + } - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic period\n"); - } + } - memset(send_buffer, 0, T300RS_BUFFER_LENGTH); - } + if(periodic.period != periodic_old.period){ + s16 period = periodic.period; - ret = t300rs_modify_envelope(t300rs, - state, - send_buffer, - level, - effect.replay.length, - effect.id, - periodic.envelope, - periodic_old.envelope); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic envelope\n"); - goto error; - } - ret = t300rs_modify_duration(t300rs, state, send_buffer); - if(ret){ - hid_err(t300rs->hdev, "failed modifying periodic duration\n"); - goto error; - } + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x0e; + send_buffer[3] = 0x08; + + send_buffer[4] = period & 0xff; + send_buffer[5] = period >> 8; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic period\n"); + } + + } + + ret = t300rs_modify_envelope(t300rs, + state, + send_buffer, + level, + effect.replay.length, + effect.id, + periodic.envelope, + periodic_old.envelope); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic envelope\n"); + goto error; + } + + ret = t300rs_modify_duration(t300rs, state, send_buffer); + if(ret){ + hid_err(t300rs->hdev, "failed modifying periodic duration\n"); + goto error; + } error: - kfree(send_buffer); - return ret; + + return ret; } static int t300rs_upload_constant(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - struct ff_effect effect = state->effect; - struct ff_constant_effect constant = state->effect.u.constant; - s16 level; - u16 duration, offset; + u8 *send_buffer = t300rs->send_buffer; + struct ff_effect effect = state->effect; + struct ff_constant_effect constant = state->effect.u.constant; + s16 level; + u16 duration, offset; + + int ret, trans; - int ret, trans; + /* some games, such as DiRT Rally 2 have a weird feeling to them, sort of + * like the wheel pulls just a bit to the right or left and then it just + * stops. I wouldn't be surprised if it's got something to do with the + * constant envelope, but right now I don't know. */ - /* some games, such as DiRT Rally 2 have a weird feeling to them, sort of - * like the wheel pulls just a bit to the right or left and then it just - * stops. I wouldn't be surprised if it's got something to do with the - * constant envelope, but right now I don't know. */ + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && + test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + return t300rs_modify_constant(t300rs, state, send_buffer); + } - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && - test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - return t300rs_modify_constant(t300rs, state, send_buffer); - } + level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } - level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } + offset = effect.replay.delay; - offset = effect.replay.delay; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x6a; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x6a; - send_buffer[3] = level & 0xff; - send_buffer[4] = level >> 8; + send_buffer[3] = level & 0xff; + send_buffer[4] = level >> 8; - t300rs_fill_envelope(send_buffer, 5, level, - duration, &constant.envelope); + t300rs_fill_envelope(send_buffer, 5, level, + duration, &constant.envelope); - send_buffer[14] = 0x4f; + send_buffer[14] = 0x4f; - send_buffer[15] = duration & 0xff; - send_buffer[16] = duration >> 8; + send_buffer[15] = duration & 0xff; + send_buffer[16] = duration >> 8; - send_buffer[19] = offset & 0xff; - send_buffer[20] = offset >> 8; + send_buffer[19] = offset & 0xff; + send_buffer[20] = offset >> 8; - send_buffer[22] = 0xff; - send_buffer[23] = 0xff; + send_buffer[22] = 0xff; + send_buffer[23] = 0xff; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed uploading constant effect\n"); - } + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading constant effect\n"); + } - kfree(send_buffer); - return ret; + + return ret; } static int t300rs_upload_ramp(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - struct ff_effect effect = state->effect; - struct ff_ramp_effect ramp = state->effect.u.ramp; - int ret, trans; - u16 difference, offset, top, bottom, duration; - s16 level; + u8 *send_buffer = t300rs->send_buffer; + struct ff_effect effect = state->effect; + struct ff_ramp_effect ramp = state->effect.u.ramp; + int ret, trans; + u16 difference, offset, top, bottom, duration; + s16 level; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && + test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + return t300rs_modify_ramp(t300rs, state, send_buffer); + } - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && - test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - return t300rs_modify_ramp(t300rs, state, send_buffer); - } + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } + top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; + bottom = ramp.end_level > ramp.start_level ? ramp.start_level : ramp.end_level; - top = ramp.end_level > ramp.start_level ? ramp.end_level : ramp.start_level; - bottom = ramp.end_level > ramp.start_level ? ramp.start_level : ramp.end_level; + difference = ((top - bottom) * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + level = (top * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + offset = effect.replay.delay; - difference = ((top - bottom) * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - level = (top * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - offset = effect.replay.delay; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x6b; - - send_buffer[3] = difference & 0xff; - send_buffer[4] = difference >> 8; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x6b; - send_buffer[5] = level & 0xff; - send_buffer[6] = level >> 8; + send_buffer[3] = difference & 0xff; + send_buffer[4] = difference >> 8; - send_buffer[9] = duration & 0xff; - send_buffer[10] = duration >> 8; + send_buffer[5] = level & 0xff; + send_buffer[6] = level >> 8; - send_buffer[12] = 0x80; + send_buffer[9] = duration & 0xff; + send_buffer[10] = duration >> 8; - t300rs_fill_envelope(send_buffer, 13, level, - effect.replay.length, &ramp.envelope); + send_buffer[12] = 0x80; - send_buffer[22] = ramp.end_level > ramp.start_level ? 0x04 : 0x05; - send_buffer[23] = 0x4f; + t300rs_fill_envelope(send_buffer, 13, level, + effect.replay.length, &ramp.envelope); - send_buffer[24] = duration & 0xff; - send_buffer[25] = duration >> 8; + send_buffer[22] = ramp.end_level > ramp.start_level ? 0x04 : 0x05; + send_buffer[23] = 0x4f; - send_buffer[28] = offset & 0xff; - send_buffer[29] = offset >> 8; + send_buffer[24] = duration & 0xff; + send_buffer[25] = duration >> 8; - send_buffer[31] = 0xff; - send_buffer[32] = 0xff; + send_buffer[28] = offset & 0xff; + send_buffer[29] = offset >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed uploading ramp"); - } + send_buffer[31] = 0xff; + send_buffer[32] = 0xff; - kfree(send_buffer); - return ret; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading ramp"); + } + + + return ret; } static int t300rs_upload_spring(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - struct ff_effect effect = state->effect; - /* we only care about the first axis */ - struct ff_condition_effect spring = state->effect.u.condition[0]; - int ret, trans; - u16 duration, right_coeff, left_coeff, deadband_right, deadband_left, offset; - - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && - test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - return t300rs_modify_damper(t300rs, state, send_buffer); - } + u8 *send_buffer = t300rs->send_buffer; + struct ff_effect effect = state->effect; + /* we only care about the first axis */ + struct ff_condition_effect spring = state->effect.u.condition[0]; + int ret, trans; + u16 duration, right_coeff, left_coeff, deadband_right, deadband_left, offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && + test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + return t300rs_modify_damper(t300rs, state, send_buffer); + } + + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x64; - - right_coeff = spring.right_coeff * spring_level / 100; - left_coeff = spring.left_coeff * spring_level / 100; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x64; - deadband_right = 0xfffe - spring.deadband - spring.center; - deadband_left = 0xfffe - spring.deadband + spring.center; + right_coeff = spring.right_coeff * spring_level / 100; + left_coeff = spring.left_coeff * spring_level / 100; - offset = effect.replay.delay; + deadband_right = 0xfffe - spring.deadband - spring.center; + deadband_left = 0xfffe - spring.deadband + spring.center; - send_buffer[3] = right_coeff & 0xff; - send_buffer[4] = right_coeff >> 8; + offset = effect.replay.delay; - send_buffer[5] = left_coeff & 0xff; - send_buffer[6] = left_coeff >> 8; + send_buffer[3] = right_coeff & 0xff; + send_buffer[4] = right_coeff >> 8; - send_buffer[7] = deadband_right & 0xff; - send_buffer[8] = deadband_right >> 8; + send_buffer[5] = left_coeff & 0xff; + send_buffer[6] = left_coeff >> 8; - send_buffer[9] = deadband_left & 0xff; - send_buffer[10] = deadband_left >> 8; + send_buffer[7] = deadband_right & 0xff; + send_buffer[8] = deadband_right >> 8; - memcpy(&send_buffer[11], spring_values, ARRAY_SIZE(spring_values)); - send_buffer[28] = 0x4f; + send_buffer[9] = deadband_left & 0xff; + send_buffer[10] = deadband_left >> 8; - send_buffer[29] = duration & 0xff; - send_buffer[30] = duration >> 8; + memcpy(&send_buffer[11], spring_values, ARRAY_SIZE(spring_values)); + send_buffer[28] = 0x4f; - send_buffer[33] = offset & 0xff; - send_buffer[34] = offset >> 8; + send_buffer[29] = duration & 0xff; + send_buffer[30] = duration >> 8; - send_buffer[36] = 0xff; - send_buffer[37] = 0xff; + send_buffer[33] = offset & 0xff; + send_buffer[34] = offset >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed uploading spring\n"); - } + send_buffer[36] = 0xff; + send_buffer[37] = 0xff; - kfree(send_buffer); - return ret; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading spring\n"); + } + + + return ret; } static int t300rs_upload_damper(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - struct ff_effect effect = state->effect; - /* we only care about the first axis */ - struct ff_condition_effect spring = state->effect.u.condition[0]; - int ret, trans, input_level; - u16 duration, right_coeff, left_coeff, deadband_right, deadband_left, offset; - - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && - test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - return t300rs_modify_damper(t300rs, state, send_buffer); - } + u8 *send_buffer = t300rs->send_buffer; + struct ff_effect effect = state->effect; + /* we only care about the first axis */ + struct ff_condition_effect spring = state->effect.u.condition[0]; + int ret, trans, input_level; + u16 duration, right_coeff, left_coeff, deadband_right, deadband_left, offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && + test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + return t300rs_modify_damper(t300rs, state, send_buffer); + } + + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } + input_level = damper_level; + if(state->effect.type == FF_FRICTION) + input_level = friction_level; - input_level = damper_level; - if(state->effect.type == FF_FRICTION) - input_level = friction_level; - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x64; - - right_coeff = spring.right_coeff * input_level / 100; - left_coeff = spring.left_coeff * input_level / 100; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x64; - deadband_right = 0xfffe - spring.deadband - spring.center; - deadband_left = 0xfffe - spring.deadband + spring.center; + right_coeff = spring.right_coeff * input_level / 100; + left_coeff = spring.left_coeff * input_level / 100; - offset = effect.replay.delay; + deadband_right = 0xfffe - spring.deadband - spring.center; + deadband_left = 0xfffe - spring.deadband + spring.center; - send_buffer[3] = right_coeff & 0xff; - send_buffer[4] = right_coeff >> 8; + offset = effect.replay.delay; - send_buffer[5] = left_coeff & 0xff; - send_buffer[6] = left_coeff >> 8; + send_buffer[3] = right_coeff & 0xff; + send_buffer[4] = right_coeff >> 8; - send_buffer[7] = deadband_right & 0xff; - send_buffer[8] = deadband_right >> 8; + send_buffer[5] = left_coeff & 0xff; + send_buffer[6] = left_coeff >> 8; - send_buffer[9] = deadband_left & 0xff; - send_buffer[10] = deadband_left >> 8; + send_buffer[7] = deadband_right & 0xff; + send_buffer[8] = deadband_right >> 8; - memcpy(&send_buffer[11], damper_values, ARRAY_SIZE(damper_values)); - send_buffer[28] = 0x4f; + send_buffer[9] = deadband_left & 0xff; + send_buffer[10] = deadband_left >> 8; - send_buffer[29] = duration & 0xff; - send_buffer[30] = duration >> 8; + memcpy(&send_buffer[11], damper_values, ARRAY_SIZE(damper_values)); + send_buffer[28] = 0x4f; - send_buffer[33] = offset & 0xff; - send_buffer[34] = offset >> 8; + send_buffer[29] = duration & 0xff; + send_buffer[30] = duration >> 8; - send_buffer[36] = 0xff; - send_buffer[37] = 0xff; + send_buffer[33] = offset & 0xff; + send_buffer[34] = offset >> 8; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed uploading spring\n"); - } + send_buffer[36] = 0xff; + send_buffer[37] = 0xff; - kfree(send_buffer); - return ret; + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading spring\n"); + } + + + return ret; } static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - struct ff_effect effect = state->effect; - struct ff_periodic_effect periodic = state->effect.u.periodic; - int ret, trans; - u16 duration, magnitude, phase, period, offset; - s16 periodic_offset; + u8 *send_buffer = t300rs->send_buffer; + struct ff_effect effect = state->effect; + struct ff_periodic_effect periodic = state->effect.u.periodic; + int ret, trans; + u16 duration, magnitude, phase, period, offset; + s16 periodic_offset; + + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && + test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + return t300rs_modify_periodic(t300rs, state, send_buffer); + } + + if(effect.replay.length == 0){ + duration = 0xffff; + } else { + duration = effect.replay.length; + } + + magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && - test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - return t300rs_modify_periodic(t300rs, state, send_buffer); - } + phase = periodic.phase; + periodic_offset = periodic.offset; + period = periodic.period; + offset = effect.replay.delay; - if(effect.replay.length == 0){ - duration = 0xffff; - } else { - duration = effect.replay.length; - } - magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff; + send_buffer[1] = effect.id + 1; + send_buffer[2] = 0x6b; - phase = periodic.phase; - periodic_offset = periodic.offset; - period = periodic.period; - offset = effect.replay.delay; - - - send_buffer[1] = effect.id + 1; - send_buffer[2] = 0x6b; - - send_buffer[3] = magnitude & 0xff; - send_buffer[4] = magnitude >> 8; + send_buffer[3] = magnitude & 0xff; + send_buffer[4] = magnitude >> 8; - send_buffer[7] = phase & 0xff; - send_buffer[8] = phase >> 8; + send_buffer[7] = phase & 0xff; + send_buffer[8] = phase >> 8; - send_buffer[5] = periodic_offset & 0xff; - send_buffer[6] = periodic_offset >> 8; + send_buffer[5] = periodic_offset & 0xff; + send_buffer[6] = periodic_offset >> 8; - send_buffer[9] = period & 0xff; - send_buffer[10] = period >> 8; + send_buffer[9] = period & 0xff; + send_buffer[10] = period >> 8; - send_buffer[12] = 0x80; + send_buffer[12] = 0x80; - t300rs_fill_envelope(send_buffer, 13, magnitude, - effect.replay.length, &periodic.envelope); + t300rs_fill_envelope(send_buffer, 13, magnitude, + effect.replay.length, &periodic.envelope); - send_buffer[21] = periodic.waveform - 0x57; - send_buffer[22] = 0x4f; + send_buffer[21] = periodic.waveform - 0x57; + send_buffer[22] = 0x4f; - send_buffer[23] = duration & 0xff; - send_buffer[24] = duration >> 8; + send_buffer[23] = duration & 0xff; + send_buffer[24] = duration >> 8; - send_buffer[27] = offset & 0xff; - send_buffer[28] = offset >> 8; + send_buffer[27] = offset & 0xff; + send_buffer[28] = offset >> 8; - send_buffer[30] = 0xff; - send_buffer[31] = 0xff; - - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(t300rs->hdev, "failed uploading periodic effect"); - } - - kfree(send_buffer); - return ret; + send_buffer[30] = 0xff; + send_buffer[31] = 0xff; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(t300rs->hdev, "failed uploading periodic effect"); + } + + + return ret; } static int t300rs_upload_effect(struct t300rs_device_entry *t300rs, struct t300rs_effect_state *state){ - switch(state->effect.type){ - case FF_CONSTANT: - return t300rs_upload_constant(t300rs, state); - case FF_RAMP: - return t300rs_upload_ramp(t300rs, state); - case FF_SPRING: - return t300rs_upload_spring(t300rs, state); - case FF_DAMPER: - case FF_FRICTION: - case FF_INERTIA: - return t300rs_upload_damper(t300rs, state); - case FF_PERIODIC: - return t300rs_upload_periodic(t300rs, state); - default: - hid_err(t300rs->hdev, "invalid effect type: %x", state->effect.type); - return -1; - } + switch(state->effect.type){ + case FF_CONSTANT: + return t300rs_upload_constant(t300rs, state); + case FF_RAMP: + return t300rs_upload_ramp(t300rs, state); + case FF_SPRING: + return t300rs_upload_spring(t300rs, state); + case FF_DAMPER: + case FF_FRICTION: + case FF_INERTIA: + return t300rs_upload_damper(t300rs, state); + case FF_PERIODIC: + return t300rs_upload_periodic(t300rs, state); + default: + hid_err(t300rs->hdev, "invalid effect type: %x", state->effect.type); + return -1; + } } static int t300rs_timer_helper(struct t300rs_device_entry *t300rs){ - struct t300rs_effect_state *state; - unsigned long jiffies_now = JIFFIES2MS(jiffies); - int max_count = 0, effect_id, ret; - - for(effect_id = 0; effect_id < T300RS_MAX_EFFECTS; ++effect_id){ - - state = &t300rs->states[effect_id]; + struct t300rs_effect_state *state; + unsigned long jiffies_now = JIFFIES2MS(jiffies); + int max_count = 0, effect_id, ret; + + for(effect_id = 0; effect_id < T300RS_MAX_EFFECTS; ++effect_id){ - if(test_bit(FF_EFFECT_PLAYING, &state->flags) && state->effect.replay.length){ - if((jiffies_now - state->start_time) >= state->effect.replay.length){ - __clear_bit(FF_EFFECT_PLAYING, &state->flags); + state = &t300rs->states[effect_id]; - /* lazy bum fix? */ - __clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); + if(test_bit(FF_EFFECT_PLAYING, &state->flags) && state->effect.replay.length){ + if((jiffies_now - state->start_time) >= state->effect.replay.length){ + __clear_bit(FF_EFFECT_PLAYING, &state->flags); - if(state->count){ - state->count--; - } + /* lazy bum fix? */ + __clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); - if(state->count){ - __set_bit(FF_EFFECT_QUEUE_START, &state->flags); - } - } - } + if(state->count){ + state->count--; + } - if(test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + if(state->count){ + __set_bit(FF_EFFECT_QUEUE_START, &state->flags); + } + } + } - ret = t300rs_upload_effect(t300rs, state); - if(ret){ - hid_err(t300rs->hdev, "failed uploading effects"); - return ret; - } - } + if(test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - if(test_bit(FF_EFFECT_QUEUE_START, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_START, &state->flags); - __set_bit(FF_EFFECT_PLAYING, &state->flags); + ret = t300rs_upload_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed uploading effects"); + return ret; + } + } - ret = t300rs_play_effect(t300rs, state); - if(ret){ - hid_err(t300rs->hdev, "failed starting effects\n"); - return ret; - } + if(test_bit(FF_EFFECT_QUEUE_START, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_START, &state->flags); + __set_bit(FF_EFFECT_PLAYING, &state->flags); - } + ret = t300rs_play_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed starting effects\n"); + return ret; + } - if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ - __clear_bit(FF_EFFECT_QUEUE_STOP, &state->flags); - __clear_bit(FF_EFFECT_PLAYING, &state->flags); + } - ret = t300rs_stop_effect(t300rs, state); - if(ret){ - hid_err(t300rs->hdev, "failed stopping effect\n"); - return ret; - } - } + if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)){ + __clear_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + __clear_bit(FF_EFFECT_PLAYING, &state->flags); - if(state->count > max_count){ - max_count = state->count; - } - } + ret = t300rs_stop_effect(t300rs, state); + if(ret){ + hid_err(t300rs->hdev, "failed stopping effect\n"); + return ret; + } + } - return max_count; + if(state->count > max_count){ + max_count = state->count; + } + } + + return max_count; } static enum hrtimer_restart t300rs_timer(struct hrtimer *t){ - struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); - int max_count; + struct t300rs_device_entry *t300rs = container_of(t, struct t300rs_device_entry, hrtimer); + int max_count; + + max_count = t300rs_timer_helper(t300rs); - max_count = t300rs_timer_helper(t300rs); - - if(max_count > 0){ - hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); - return HRTIMER_RESTART; - } else { - return HRTIMER_NORESTART; - } + if(max_count > 0){ + hrtimer_forward_now(&t300rs->hrtimer, ms_to_ktime(timer_msecs)); + return HRTIMER_RESTART; + } else { + return HRTIMER_NORESTART; + } } static int t300rs_upload(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old){ - struct hid_device *hdev = input_get_drvdata(dev); - struct t300rs_device_entry *t300rs; - struct t300rs_effect_state *state; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + struct t300rs_effect_state *state; - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - if(effect->type == FF_PERIODIC && effect->u.periodic.period == 0){ - return -EINVAL; - } + if(effect->type == FF_PERIODIC && effect->u.periodic.period == 0){ + return -EINVAL; + } - if(effect->id > t300rs->max_id){ - t300rs->max_id = effect->id; - } + state = &t300rs->states[effect->id]; - state = &t300rs->states[effect->id]; + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); - spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); + state->effect = *effect; + if(old){ + state->old = *old; + __set_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); + } else { + __clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); + } + __set_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); - state->effect = *effect; - if(old){ - state->old = *old; - __set_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); - } else { - __clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags); - } - __set_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags); + spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); - spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); - - return 0; + return 0; } static int t300rs_play(struct input_dev *dev, int effect_id, int value){ - struct hid_device *hdev = input_get_drvdata(dev); - struct t300rs_device_entry *t300rs; - struct t300rs_effect_state *state; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + struct t300rs_effect_state *state; + + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + state = &t300rs->states[effect_id]; - state = &t300rs->states[effect_id]; + if(&state->effect == 0) + return 0; - if(&state->effect == 0) - return 0; - - spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); + spin_lock_irqsave(&t300rs->lock, t300rs->lock_flags); - if(value > 0){ - state->count = value; - state->start_time = JIFFIES2MS(jiffies); - __set_bit(FF_EFFECT_QUEUE_START, &state->flags); + if(value > 0){ + state->count = value; + state->start_time = JIFFIES2MS(jiffies); + __set_bit(FF_EFFECT_QUEUE_START, &state->flags); - if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)) - __clear_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + if(test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)) + __clear_bit(FF_EFFECT_QUEUE_STOP, &state->flags); - } else { - __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); - } + } else { + __set_bit(FF_EFFECT_QUEUE_STOP, &state->flags); + } - if(!hrtimer_active(&t300rs->hrtimer)){ - hrtimer_start(&t300rs->hrtimer, ms_to_ktime(timer_msecs), HRTIMER_MODE_REL); - } + if(!hrtimer_active(&t300rs->hrtimer)){ + hrtimer_start(&t300rs->hrtimer, ms_to_ktime(timer_msecs), HRTIMER_MODE_REL); + } - spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); - return 0; + spin_unlock_irqrestore(&t300rs->lock, t300rs->lock_flags); + return 0; } static ssize_t t300rs_spring_level_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count){ - unsigned value = simple_strtoul(buf, NULL, 10); + const char *buf, size_t count){ + unsigned value = simple_strtoul(buf, NULL, 10); - if(value > 100) - value = 100; + if(value > 100) + value = 100; - spring_level = value; + spring_level = value; - return count; + return count; } static ssize_t t300rs_spring_level_show(struct device *dev, struct device_attribute *attr, char *buf){ - size_t count; + size_t count; - count = scnprintf(buf, PAGE_SIZE, "%u\n", spring_level); + count = scnprintf(buf, PAGE_SIZE, "%u\n", spring_level); - return count; + return count; } static DEVICE_ATTR(spring_level, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_spring_level_show, t300rs_spring_level_store); static ssize_t t300rs_damper_level_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count){ - unsigned value = simple_strtoul(buf, NULL, 10); + const char *buf, size_t count){ + unsigned value = simple_strtoul(buf, NULL, 10); - if(value > 100) - value = 100; + if(value > 100) + value = 100; - damper_level = value; + damper_level = value; - return count; + return count; } static ssize_t t300rs_damper_level_show(struct device *dev, struct device_attribute *attr, char *buf){ - size_t count; + size_t count; - count = scnprintf(buf, PAGE_SIZE, "%u\n", damper_level); + count = scnprintf(buf, PAGE_SIZE, "%u\n", damper_level); - return count; + return count; } static DEVICE_ATTR(damper_level, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_damper_level_show, t300rs_damper_level_store); static ssize_t t300rs_friction_level_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count){ - unsigned value = simple_strtoul(buf, NULL, 10); + const char *buf, size_t count){ + unsigned value = simple_strtoul(buf, NULL, 10); - if(value > 100) - value = 100; + if(value > 100) + value = 100; - friction_level = value; + friction_level = value; - return count; + return count; } static ssize_t t300rs_friction_level_show(struct device *dev, struct device_attribute *attr, char *buf){ - size_t count; + size_t count; - count = scnprintf(buf, PAGE_SIZE, "%u\n", friction_level); + count = scnprintf(buf, PAGE_SIZE, "%u\n", friction_level); - return count; + return count; } static DEVICE_ATTR(friction_level, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_friction_level_show, t300rs_friction_level_store); /* we should set a default range */ static ssize_t t300rs_range_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count){ - struct hid_device *hdev = to_hid_device(dev); - struct t300rs_device_entry *t300rs; - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - u16 range = simple_strtoul(buf, NULL, 10); - int ret, trans; + const char *buf, size_t count){ + struct hid_device *hdev = to_hid_device(dev); + struct t300rs_device_entry *t300rs; + u8 *send_buffer; + u16 range = simple_strtoul(buf, NULL, 10); + int ret, trans; - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - if(range < 40){ - range = 40; - } + send_buffer = t300rs->send_buffer; - if(range > 1080){ - range = 1080; - } + if(range < 40){ + range = 40; + } - range *= 0x3c; + if(range > 1080){ + range = 1080; + } - - send_buffer[0] = 0x08; - send_buffer[1] = 0x11; - send_buffer[2] = range & 0xff; - send_buffer[3] = range >> 8; + range *= 0x3c; - ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed sending interrupts\n"); - return -1; - } - t300rs->range = range / 0x3c; - kfree(send_buffer); - return count; + send_buffer[0] = 0x08; + send_buffer[1] = 0x11; + send_buffer[2] = range & 0xff; + send_buffer[3] = range >> 8; + + ret = t300rs_send_int(t300rs->input_dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + return -1; + } + + t300rs->range = range / 0x3c; + + return count; } static ssize_t t300rs_range_show(struct device *dev, struct device_attribute *attr, - char *buf){ - struct hid_device *hdev = to_hid_device(dev); - struct t300rs_device_entry *t300rs; - size_t count = 0; + char *buf){ + struct hid_device *hdev = to_hid_device(dev); + struct t300rs_device_entry *t300rs; + size_t count = 0; - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - count = scnprintf(buf, PAGE_SIZE, "%u\n", t300rs->range); - return count; + count = scnprintf(buf, PAGE_SIZE, "%u\n", t300rs->range); + return count; } static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, t300rs_range_show, t300rs_range_store); static void t300rs_set_autocenter(struct input_dev *dev, u16 value){ - struct hid_device *hdev = input_get_drvdata(dev); - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - int ret, trans; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + u8 *send_buffer; + int ret, trans; + + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return; + } - - send_buffer[0] = 0x08; - send_buffer[1] = 0x04; - send_buffer[2] = 0x01; - - ret = t300rs_send_int(dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed setting autocenter"); - } + send_buffer = t300rs->send_buffer; - send_buffer[0] = 0x08; - send_buffer[1] = 0x03; - - send_buffer[2] = value & 0xff; - send_buffer[3] = value >> 8; - ret = t300rs_send_int(dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed setting autocenter"); - } + send_buffer[0] = 0x08; + send_buffer[1] = 0x04; + send_buffer[2] = 0x01; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed setting autocenter"); + } + + send_buffer[0] = 0x08; + send_buffer[1] = 0x03; + + send_buffer[2] = value & 0xff; + send_buffer[3] = value >> 8; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed setting autocenter"); + } + - kfree(send_buffer); } static void t300rs_set_gain(struct input_dev *dev, u16 gain){ - struct hid_device *hdev = input_get_drvdata(dev); - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - int ret, trans; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + u8 *send_buffer; + int ret, trans; + + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return; + } + + send_buffer = t300rs->send_buffer; + send_buffer[0] = 0x02; + send_buffer[1] = SCALE_VALUE_U16(gain, 8); + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed setting gain: %i\n", ret); + } - - send_buffer[0] = 0x02; - send_buffer[1] = SCALE_VALUE_U16(gain, 8); - - ret = t300rs_send_int(dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed setting gain: %i\n", ret); - } - kfree(send_buffer); } static void t300rs_destroy(struct ff_device *ff){ - /* maybe not necessary? */ - return; + /* maybe not necessary? */ + return; } static int t300rs_open(struct input_dev *dev){ - struct t300rs_device_entry *t300rs; - struct hid_device *hdev = input_get_drvdata(dev); - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - int ret, trans; - - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return -1; - } + struct t300rs_device_entry *t300rs; + struct hid_device *hdev = input_get_drvdata(dev); + u8 *send_buffer; + int ret, trans; + + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return -1; + } - send_buffer[0] = 0x01; - send_buffer[1] = 0x05; + send_buffer = t300rs->send_buffer; + + send_buffer[0] = 0x01; + send_buffer[1] = 0x05; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } - ret = t300rs_send_int(dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed sending interrupts\n"); - goto err; - } - err: - kfree(send_buffer); - return t300rs->open(dev); + + return t300rs->open(dev); } static void t300rs_close(struct input_dev *dev){ - int ret, trans; - struct hid_device *hdev = input_get_drvdata(dev); - struct t300rs_device_entry *t300rs; - u8 *send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_ATOMIC); - - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return; - } + int ret, trans; + struct hid_device *hdev = input_get_drvdata(dev); + struct t300rs_device_entry *t300rs; + u8 *send_buffer; + + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return; + } - send_buffer[0] = 0x01; + send_buffer = t300rs->send_buffer; - ret = t300rs_send_int(dev, send_buffer, &trans); - if(ret){ - hid_err(hdev, "failed sending interrupts\n"); - goto err; - } + send_buffer[0] = 0x01; + + ret = t300rs_send_int(dev, send_buffer, &trans); + if(ret){ + hid_err(hdev, "failed sending interrupts\n"); + goto err; + } err: - kfree(send_buffer); - t300rs->close(dev); - return; + + t300rs->close(dev); + return; } -int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ - struct t300rs_device_entry *t300rs; - struct t300rs_data *drv_data; - struct list_head *report_list; - struct hid_input *hidinput = list_entry(hdev->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; - struct device *dev = &hdev->dev; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - struct hid_report *report; - struct ff_device *ff; - u8 *transfer = kzalloc(64, GFP_ATOMIC); - char range[10] = "900"; /* max */ - int i, ret; +static int t300rs_create_files(struct hid_device *hdev){ + int ret; - drv_data = hid_get_drvdata(hdev); - if(!drv_data){ - hid_err(hdev, "private driver data not allocated\n"); - ret = -ENOMEM; - goto err; - } + ret = device_create_file(&hdev->dev, &dev_attr_range); + if(ret){ + hid_warn(hdev, "unable to create sysfs interface for range\n"); + goto attr_range_err; + } - t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_ATOMIC); - if(!t300rs){ - hid_err(hdev, "device entry could not be created\n"); - ret = -ENOMEM; - goto t300rs_err; - } + ret = device_create_file(&hdev->dev, &dev_attr_spring_level); + if(ret){ + hid_warn(hdev, "unable to create sysfs interface for spring_level\n"); + goto attr_spring_err; + } - t300rs->input_dev = input_dev; - t300rs->hdev = hdev; - t300rs->usbdev = usbdev; - t300rs->usbif = usbif; - t300rs->max_id = 0; - t300rs->states = kmalloc(sizeof(struct t300rs_effect_state) * 0x60, GFP_ATOMIC); + ret = device_create_file(&hdev->dev, &dev_attr_damper_level); + if(ret){ + hid_warn(hdev, "unable to create sysfs interface for damper_level\n"); + goto attr_damper_err; + } - if(!t300rs->states){ - hid_err(hdev, "effect states could not be created\n"); - ret = -ENOMEM; - goto states_err; - } + ret = device_create_file(&hdev->dev, &dev_attr_friction_level); + if(ret){ + hid_warn(hdev, "unable to create sysfs interface for friction_level\n"); + goto attr_friction_err; + } - spin_lock_init(&t300rs->lock); + return ret; + + // if the creation of dev_attr_friction fails, we don't need to remove it + // device_remove_file(&hdev->dev, &dev_attr_friction_level); +attr_friction_err: + device_remove_file(&hdev->dev, &dev_attr_damper_level); +attr_damper_err: + device_remove_file(&hdev->dev, &dev_attr_spring_level); +attr_spring_err: + device_remove_file(&hdev->dev, &dev_attr_range); +attr_range_err: + return ret; +} - drv_data->device_props = t300rs; +static int t300rs_init(struct hid_device *hdev, const signed short *ff_bits){ + struct t300rs_device_entry *t300rs; + struct t300rs_data *drv_data; + struct list_head *report_list; + struct hid_input *hidinput = list_entry(hdev->inputs.next, + struct hid_input, list); + struct input_dev *input_dev = hidinput->input; + struct device *dev = &hdev->dev; + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + struct ff_device *ff; + char range[10] = "900"; // max + int i, ret; - report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; - list_for_each_entry(report, report_list, list){ - int fieldnum; + drv_data = hid_get_drvdata(hdev); + if(!drv_data){ + hid_err(hdev, "private driver data not allocated\n"); + ret = -ENOMEM; + goto err; + } - for(fieldnum = 0; fieldnum < report->maxfield; ++fieldnum){ - struct hid_field *field = report->field[fieldnum]; + t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL); + if(!t300rs){ + hid_err(hdev, "device entry could not be created\n"); + ret = -ENOMEM; + goto t300rs_err; + } - if(field->maxusage <= 0){ - continue; - } + t300rs->input_dev = input_dev; + t300rs->hdev = hdev; + t300rs->usbdev = usbdev; + t300rs->usbif = usbif; - switch(field->usage[0].hid){ - case 0xff000060: - if(field->report_count < 2){ - hid_warn(hdev, "ignoring FF field with report_count < 2\n"); - continue; - } + t300rs->states = kzalloc(sizeof(struct t300rs_effect_state) * T300RS_MAX_EFFECTS, GFP_KERNEL); + if(!t300rs->states){ + hid_err(hdev, "effect states could not be created\n"); + ret = -ENOMEM; + goto states_err; + } - if(field->logical_maximum == field->logical_minimum){ - hid_warn(hdev, "ignoring FF field with l_max == l_min"); - continue; - } + t300rs->send_buffer = kzalloc(T300RS_BUFFER_LENGTH, GFP_KERNEL); + if(!t300rs->send_buffer){ + hid_err(hdev, "send_buffer could not be created\n"); + ret = -ENOMEM; + goto send_err; + } - if(t300rs->report && t300rs->report != report){ - hid_warn(hdev, "ignoring FF field in other report\n"); - continue; - } + t300rs->firmware_response = kzalloc(sizeof(struct t300rs_firmware_response), GFP_KERNEL); + if(!t300rs->firmware_response){ + hid_err(hdev, "firmware_response could not be created\n"); + ret = -ENOMEM; + goto firmware_err; + } - if(t300rs->ff_field && t300rs->ff_field != field){ - hid_warn(hdev, "ignoring duplicate FF field\n"); - continue; - } + // Check firmware version + ret = usb_control_msg(t300rs->usbdev, + usb_rcvctrlpipe(t300rs->usbdev, 0), + t300rs_firmware_request.bRequest, + t300rs_firmware_request.bRequestType, + t300rs_firmware_request.wValue, + t300rs_firmware_request.wIndex, + t300rs->firmware_response, + t300rs_firmware_request.wLength, + USB_CTRL_SET_TIMEOUT + ); - t300rs->report = report; - t300rs->ff_field = field; + // Educated guess + if(t300rs->firmware_response->firmware_version < 31 && ret >= 0){ + hid_err(t300rs->hdev, + "firmware version %i is too old, please update the firmware " + "using the official Thrustmaster tools. This will have to " + "be done outside of Linux.\n", + t300rs->firmware_response->firmware_version + ); - for(i = 0; ff_bits[i] >= 0; ++i){ - set_bit(ff_bits[i], input_dev->ffbit); - } + ret = -ENOSYS; + goto out; + } - break; + spin_lock_init(&t300rs->lock); - default: - hid_warn(hdev, "ignoring unknown output usage: %i\n", field->usage[0].hid); - continue; - } - } - } + drv_data->device_props = t300rs; - if(!t300rs->report){ - hid_err(hdev, "can't find FF field in output reports\n"); - ret = -ENODEV; - goto out; - } + report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; - ret = input_ff_create(input_dev, T300RS_MAX_EFFECTS); - if(ret){ - hid_err(hdev, "could not create input_ff\n"); - goto out; - } + // because we set the rdesc, we know exactly which report and field to use + t300rs->report = list_entry(report_list->next, struct hid_report, list); + t300rs->ff_field = t300rs->report->field[0]; - ff = input_dev->ff; - ff->upload = t300rs_upload; - ff->playback = t300rs_play; - ff->set_gain = t300rs_set_gain; - ff->set_autocenter = t300rs_set_autocenter; - ff->destroy = t300rs_destroy; + // set ff capabilities + for(i = 0; ff_bits[i] >= 0; ++i){ + __set_bit(ff_bits[i], input_dev->ffbit); + } - t300rs->open = input_dev->open; - t300rs->close = input_dev->close; + ret = input_ff_create(input_dev, T300RS_MAX_EFFECTS); + if(ret){ + hid_err(hdev, "could not create input_ff\n"); + goto out; + } - input_dev->open = t300rs_open; - input_dev->close = t300rs_close; + ff = input_dev->ff; + ff->upload = t300rs_upload; + ff->playback = t300rs_play; + ff->set_gain = t300rs_set_gain; + ff->set_autocenter = t300rs_set_autocenter; + ff->destroy = t300rs_destroy; - ret = device_create_file(&hdev->dev, &dev_attr_range); - if(ret){ - hid_warn(hdev, "unable to create sysfs interface for range\n"); - goto out; - } + t300rs->open = input_dev->open; + t300rs->close = input_dev->close; - ret = device_create_file(&hdev->dev, &dev_attr_spring_level); - if(ret){ - hid_warn(hdev, "unable to create sysfs interface for spring_level\n"); - goto out; - } + input_dev->open = t300rs_open; + input_dev->close = t300rs_close; - ret = device_create_file(&hdev->dev, &dev_attr_damper_level); - if(ret){ - hid_warn(hdev, "unable to create sysfs interface for damper_level\n"); - goto out; - } + ret = t300rs_create_files(hdev); + if(ret){ + // this might not be a catastrophic issue, but it could affect + // programs such as oversteer, best play it safe + hid_err(hdev, "could not create sysfs files\n"); + goto out; + } - ret = device_create_file(&hdev->dev, &dev_attr_friction_level); - if(ret){ - hid_warn(hdev, "unable to create sysfs interface for friction_level\n"); - goto out; - } - hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - t300rs->hrtimer.function = t300rs_timer; - - t300rs_range_store(dev, &dev_attr_range, range, 10); - t300rs_set_gain(input_dev, 0xffff); + hrtimer_init(&t300rs->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t300rs->hrtimer.function = t300rs_timer; - kfree(transfer); + t300rs_range_store(dev, &dev_attr_range, range, 10); + t300rs_set_gain(input_dev, 0xffff); - hid_info(hdev, "force feedback for T300RS\n"); - return 0; + hid_info(hdev, "force feedback for T300RS\n"); + return 0; out: - kfree(t300rs->states); + kfree(t300rs->firmware_response); +firmware_err: + kfree(t300rs->send_buffer); +send_err: + kfree(t300rs->states); states_err: - kfree(t300rs); + kfree(t300rs); t300rs_err: - kfree(drv_data); + kfree(drv_data); err: - hid_err(hdev, "failed creating force feedback device\n"); - return ret; + hid_err(hdev, "failed creating force feedback device\n"); + return ret; } static int t300rs_probe(struct hid_device *hdev, const struct hid_device_id *id){ - int ret; - struct t300rs_data *drv_data; + int ret; + struct t300rs_data *drv_data; - spin_lock_init(&lock); + spin_lock_init(&lock); - drv_data = kzalloc(sizeof(struct t300rs_data), GFP_ATOMIC); - if(!drv_data){ - hid_err(hdev, "out of memory\n"); - ret = -ENOMEM; - goto err; - } + drv_data = kzalloc(sizeof(struct t300rs_data), GFP_KERNEL); + if(!drv_data){ + hid_err(hdev, "out of memory\n"); + ret = -ENOMEM; + goto err; + } - drv_data->quirks = id->driver_data; - hid_set_drvdata(hdev, (void*)drv_data); + drv_data->quirks = id->driver_data; + hid_set_drvdata(hdev, (void*)drv_data); - ret = hid_parse(hdev); - if(ret){ - hid_err(hdev, "parse failed\n"); - goto err; - } + ret = hid_parse(hdev); + if(ret){ + hid_err(hdev, "parse failed\n"); + goto err; + } - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if(ret){ - hid_err(hdev, "hw start failed\n"); - goto err; - } + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + if(ret){ + hid_err(hdev, "hw start failed\n"); + goto err; + } - ret = t300rs_init(hdev, (void*)id->driver_data); - if(ret){ - hid_err(hdev, "t300rs_init failed\n"); - goto err; - } - return 0; + ret = t300rs_init(hdev, (void*)id->driver_data); + if(ret){ + hid_err(hdev, "t300rs_init failed\n"); + goto err; + } + return 0; err: - kfree(drv_data); - return ret; + return ret; } static void t300rs_remove(struct hid_device *hdev){ - struct t300rs_device_entry *t300rs; - struct t300rs_data *drv_data; + struct t300rs_device_entry *t300rs; + struct t300rs_data *drv_data; - drv_data = hid_get_drvdata(hdev); - t300rs = t300rs_get_device(hdev); - if(!t300rs){ - hid_err(hdev, "could not get device\n"); - return; - } + drv_data = hid_get_drvdata(hdev); + t300rs = t300rs_get_device(hdev); + if(!t300rs){ + hid_err(hdev, "could not get device\n"); + return; + } - hrtimer_cancel(&t300rs->hrtimer); + hrtimer_cancel(&t300rs->hrtimer); - device_remove_file(&hdev->dev, &dev_attr_range); - device_remove_file(&hdev->dev, &dev_attr_spring_level); - device_remove_file(&hdev->dev, &dev_attr_damper_level); - device_remove_file(&hdev->dev, &dev_attr_friction_level); + device_remove_file(&hdev->dev, &dev_attr_range); + device_remove_file(&hdev->dev, &dev_attr_spring_level); + device_remove_file(&hdev->dev, &dev_attr_damper_level); + device_remove_file(&hdev->dev, &dev_attr_friction_level); - hid_hw_stop(hdev); - kfree(t300rs->states); - kfree(drv_data); - kfree(t300rs); + hid_hw_stop(hdev); + kfree(t300rs->states); + kfree(t300rs->send_buffer); + kfree(t300rs->firmware_response); + kfree(t300rs); + kfree(drv_data); - return; + return; } static __u8 *t300rs_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){ - rdesc = t300rs_rdesc_fixed; - *rsize = sizeof(t300rs_rdesc_fixed); - return rdesc; + rdesc = t300rs_rdesc_fixed; + *rsize = sizeof(t300rs_rdesc_fixed); + return rdesc; } static const struct hid_device_id t300rs_devices[] = { - {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66e), - .driver_data = (unsigned long)t300rs_ff_effects}, - {} + {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb66e), + .driver_data = (unsigned long)t300rs_ff_effects}, + {} }; MODULE_DEVICE_TABLE(hid, t300rs_devices); static struct hid_driver t300rs_driver = { - .name = "t300rs", - .id_table = t300rs_devices, - .probe = t300rs_probe, - .remove = t300rs_remove, - .report_fixup = t300rs_report_fixup, + .name = "t300rs", + .id_table = t300rs_devices, + .probe = t300rs_probe, + .remove = t300rs_remove, + .report_fixup = t300rs_report_fixup, }; module_hid_driver(t300rs_driver); diff --git a/hid-tmt300rs.h b/hid-tmt300rs.h index 2eef09d..28b44ab 100644 --- a/hid-tmt300rs.h +++ b/hid-tmt300rs.h @@ -1,10 +1,14 @@ -#include "hid-tm.h" -#include "usbhid.h" +#include <linux/hid.h> +#include <linux/usb.h> +#include <linux/input.h> +#include <linux/module.h> #include <linux/hrtimer.h> #include <linux/slab.h> #include <linux/ktime.h> #include <linux/fixp-arith.h> +#define USB_VENDOR_ID_THRUSTMASTER 0x044f + #define T300RS_MAX_EFFECTS 16 #define T300RS_BUFFER_LENGTH 63 @@ -33,69 +37,119 @@ spinlock_t data_lock; unsigned long data_flags; static const signed short t300rs_ff_effects[] = { - FF_CONSTANT, - FF_RAMP, - FF_SPRING, - FF_DAMPER, - FF_FRICTION, - FF_INERTIA, - FF_PERIODIC, - FF_SINE, - FF_TRIANGLE, - FF_SQUARE, - FF_SAW_UP, - FF_SAW_DOWN, - FF_AUTOCENTER, - FF_GAIN, - -1 + FF_CONSTANT, + FF_RAMP, + FF_SPRING, + FF_DAMPER, + FF_FRICTION, + FF_INERTIA, + FF_PERIODIC, + FF_SINE, + FF_TRIANGLE, + FF_SQUARE, + FF_SAW_UP, + FF_SAW_DOWN, + FF_AUTOCENTER, + FF_GAIN, + -1 }; struct t300rs_effect_state { - struct ff_effect effect; - struct ff_effect old; - bool old_set; - unsigned long flags; - unsigned long start_time; - unsigned long count; + struct ff_effect effect; + struct ff_effect old; + bool old_set; + unsigned long flags; + unsigned long start_time; + unsigned long count; +}; + +struct __packed t300rs_firmware_response { + uint8_t unknown0; + uint8_t unknown1; + uint8_t firmware_version; + uint8_t unknown2; }; + +struct usb_ctrlrequest t300rs_firmware_request = { + .bRequestType = 0xc1, + .bRequest = 86, + .wValue = 0, + .wIndex = 0, + .wLength = 8 +}; + + struct t300rs_device_entry { - struct hid_device *hdev; - struct input_dev *input_dev; - struct hid_report *report; - struct hid_field *ff_field; - struct usb_device *usbdev; - struct usb_interface *usbif; - struct t300rs_effect_state *states; - struct hrtimer hrtimer; + struct hid_device *hdev; + struct input_dev *input_dev; + struct hid_report *report; + struct hid_field *ff_field; + struct usb_device *usbdev; + struct usb_interface *usbif; + struct t300rs_effect_state *states; + struct t300rs_firmware_response *firmware_response; + struct hrtimer hrtimer; - int (*open)(struct input_dev *dev); - void (*close)(struct input_dev *dev); + int (*open)(struct input_dev *dev); + void (*close)(struct input_dev *dev); - spinlock_t lock; - unsigned long lock_flags; + spinlock_t lock; + unsigned long lock_flags; - int open_count; - - int max_id; - u16 range; - u8 effects_used; + u8 *send_buffer; + + u16 range; + u8 effects_used; }; struct t300rs_data{ - unsigned long quirks; - void *device_props; + unsigned long quirks; + void *device_props; }; -static __u8 t300rs_rdesc_fixed[] = {0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x07, 0x09, 0x30, 0x15, 0x00, 0x27, 0xff, 0xff, 0x00, 0x00, 0x35, 0x00, 0x47, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, 0x95, 0x01, 0x81, 0x02, 0x09, 0x35, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x81, 0x02, 0x09, 0x32, 0x81, 0x02, 0x09, 0x31, 0x81, 0x02, 0x81, 0x03, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0d, 0x25, 0x01, 0x45, 0x01, 0x75, 0x01, 0x95, 0x0d, 0x81, 0x02, 0x75, 0x0b, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x39, 0x25, 0x07, 0x46, 0x3b, 0x01, 0x55, 0x00, 0x65, 0x14, 0x75, 0x04, 0x81, 0x42, 0x65, 0x00, 0x81, 0x03, 0x85, 0x60, // here 0x0a - 0x06, 0x00, 0xff, 0x09, 0x60, // here 0x0a - 0x75, 0x08, 0x95, 0x3f, 0x26, 0xff, 0x7f, 0x15, 0x00, 0x46, 0xff, 0x7f, 0x36, 0x00, 0x80, 0x91, 0x02, 0x85, 0x02, 0x09, 0x02, 0x81, 0x02, 0x09, 0x14, 0x85, 0x14, 0x81, 0x02, 0xc0, 0xc0,}; +static __u8 t300rs_rdesc_fixed[] = { + 0x05, 0x01, 0x09, 0x04, 0xa1, + 0x01, 0x09, 0x01, 0xa1, 0x00, + 0x85, 0x07, 0x09, 0x30, 0x15, + 0x00, 0x27, 0xff, 0xff, 0x00, + 0x00, 0x35, 0x00, 0x47, 0xff, + 0xff, 0x00, 0x00, 0x75, 0x10, + 0x95, 0x01, 0x81, 0x02, 0x09, + 0x35, 0x26, 0xff, 0x03, 0x46, + 0xff, 0x03, 0x81, 0x02, 0x09, + 0x32, 0x81, 0x02, 0x09, 0x31, + 0x81, 0x02, 0x81, 0x03, 0x05, + 0x09, 0x19, 0x01, 0x29, 0x0d, + 0x25, 0x01, 0x45, 0x01, 0x75, + 0x01, 0x95, 0x0d, 0x81, 0x02, + 0x75, 0x0b, 0x95, 0x01, 0x81, + 0x03, 0x05, 0x01, 0x09, 0x39, + 0x25, 0x07, 0x46, 0x3b, 0x01, + 0x55, 0x00, 0x65, 0x14, 0x75, + 0x04, 0x81, 0x42, 0x65, 0x00, + 0x81, 0x03, 0x85, 0x60, // here 0x0a + 0x06, 0x00, 0xff, 0x09, 0x60, // here 0x0a + 0x75, 0x08, 0x95, 0x3f, 0x26, + 0xff, 0x7f, 0x15, 0x00, 0x46, + 0xff, 0x7f, 0x36, 0x00, 0x80, + 0x91, 0x02, 0x85, 0x02, 0x09, + 0x02, 0x81, 0x02, 0x09, 0x14, + 0x85, 0x14, 0x81, 0x02, 0xc0, + 0xc0, +}; static u8 spring_values[] = { - 0xa6, 0x6a, 0xa6, 0x6a, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xdf, 0x58, 0xa6, 0x6a, 0x06 + 0xa6, 0x6a, 0xa6, 0x6a, 0xfe, + 0xff, 0xfe, 0xff, 0xfe, 0xff, + 0xfe, 0xff, 0xdf, 0x58, 0xa6, + 0x6a, 0x06 }; static u8 damper_values[] = { - 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0xfc, 0x7f, 0x07 + 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, + 0xff, 0xfe, 0xff, 0xfe, 0xff, + 0xfe, 0xff, 0xfc, 0x7f, 0xfc, + 0x7f, 0x07 }; diff --git a/usbhid.h b/usbhid.h deleted file mode 100644 index 8ab2917..0000000 --- a/usbhid.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef __USBHID_H -#define __USBHID_H - -/* - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2001 Vojtech Pavlik - * Copyright (c) 2006 Jiri Kosina - */ - -/* - */ - -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/mutex.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/workqueue.h> -#include <linux/input.h> - -/* API provided by hid-core.c for USB HID drivers */ -void usbhid_init_reports(struct hid_device *hid); -struct usb_interface *usbhid_find_interface(int minor); - -/* iofl flags */ -#define HID_CTRL_RUNNING 1 -#define HID_OUT_RUNNING 2 -#define HID_IN_RUNNING 3 -#define HID_RESET_PENDING 4 -#define HID_SUSPENDED 5 -#define HID_CLEAR_HALT 6 -#define HID_DISCONNECTED 7 -#define HID_STARTED 8 -#define HID_KEYS_PRESSED 10 -#define HID_NO_BANDWIDTH 11 -#define HID_RESUME_RUNNING 12 -/* - * The device is opened, meaning there is a client that is interested - * in data coming from the device. - */ -#define HID_OPENED 13 -/* - * We are polling input endpoint by [re]submitting IN URB, because - * either HID device is opened or ALWAYS POLL quirk is set for the - * device. - */ -#define HID_IN_POLLING 14 - -/* - * USB-specific HID struct, to be pointed to - * from struct hid_device->driver_data - */ - -struct usbhid_device { - struct hid_device *hid; /* pointer to corresponding HID dev */ - - struct usb_interface *intf; /* USB interface */ - int ifnum; /* USB interface number */ - - unsigned int bufsize; /* URB buffer size */ - - struct urb *urbin; /* Input URB */ - char *inbuf; /* Input buffer */ - dma_addr_t inbuf_dma; /* Input buffer dma */ - - struct urb *urbctrl; /* Control URB */ - struct usb_ctrlrequest *cr; /* Control request struct */ - struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */ - unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ - char *ctrlbuf; /* Control buffer */ - dma_addr_t ctrlbuf_dma; /* Control buffer dma */ - unsigned long last_ctrl; /* record of last output for timeouts */ - - struct urb *urbout; /* Output URB */ - struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ - unsigned char outhead, outtail; /* Output pipe fifo head & tail */ - char *outbuf; /* Output buffer */ - dma_addr_t outbuf_dma; /* Output buffer dma */ - unsigned long last_out; /* record of last output for timeouts */ - - spinlock_t lock; /* fifo spinlock */ - unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ - struct timer_list io_retry; /* Retry timer */ - unsigned long stop_retry; /* Time to give up, in jiffies */ - unsigned int retry_delay; /* Delay length in ms */ - struct work_struct reset_work; /* Task context for resets */ - wait_queue_head_t wait; /* For sleeping */ -}; - -#define hid_to_usb_dev(hid_dev) \ - to_usb_device(hid_dev->dev.parent->parent) - -#endif |
