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 /hid-tmt300rs.c | |
| parent | c2be549438657a7e0b863a1ed58ba17e8fb5ff33 (diff) | |
| download | hid-tmff2-301f7fa87fa2bafbd9ed3436aa7eb865b341563c.tar.gz hid-tmff2-301f7fa87fa2bafbd9ed3436aa7eb865b341563c.zip | |
Merge branch 'minalloc'
Diffstat (limited to 'hid-tmt300rs.c')
| -rw-r--r-- | hid-tmt300rs.c | 2216 |
1 files changed, 1123 insertions, 1093 deletions
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); |
