aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hid-tmff2.c52
-rw-r--r--src/tmt300rs/hid-tmt300rs.c10
2 files changed, 53 insertions, 9 deletions
diff --git a/src/hid-tmff2.c b/src/hid-tmff2.c
index b028a28..0149d99 100644
--- a/src/hid-tmff2.c
+++ b/src/hid-tmff2.c
@@ -306,15 +306,11 @@ static void tmff2_work_handler(struct work_struct *w)
effect_length = state->effect.replay.length;
if (test_bit(FF_EFFECT_PLAYING, &state->flags) && effect_length) {
- if ((time_now - state->start_time) >= effect_length) {
+ if ((time_now - state->start_time) >= effect_length * state->count) {
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
__clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags);
- if (state->count)
- state->count--;
-
- if (state->count)
- __set_bit(FF_EFFECT_QUEUE_START, &state->flags);
+ state->count = 0;
}
}
@@ -359,6 +355,7 @@ static void tmff2_work_handler(struct work_struct *w)
max_count = state->count;
spin_unlock(&tmff2->lock);
+
/* wait for each effect update to actually be sent out to avoid
* filling up usb output queue */
hid_hw_wait(tmff2->hdev);
@@ -368,6 +365,32 @@ static void tmff2_work_handler(struct work_struct *w)
schedule_delayed_work(&tmff2->work, msecs_to_jiffies(timer_msecs));
}
+static void tmff2_rewrite_rumble(struct ff_effect *effect)
+{
+ /* this is more or less directly copied from
+ * https://elixir.bootlin.com/linux/latest/source/drivers/input/ff-core.c#L48
+ * except we set the direction to east, to make sure the direction
+ * scaling doesn't do any funny business */
+ int magnitude = 0;
+ if (effect->type != FF_RUMBLE)
+ return;
+
+ magnitude = effect->u.rumble.strong_magnitude / 3
+ + effect->u.rumble.weak_magnitude / 6;
+
+ effect->type = FF_PERIODIC;
+ effect->direction = 16384;
+ effect->u.periodic.waveform = FF_SINE;
+ effect->u.periodic.period = 50;
+ effect->u.periodic.magnitude = magnitude;
+ effect->u.periodic.offset = 0;
+ effect->u.periodic.phase = 0;
+ effect->u.periodic.envelope.attack_length = 0;
+ effect->u.periodic.envelope.attack_level = 0;
+ effect->u.periodic.envelope.fade_length = 0;
+ effect->u.periodic.envelope.fade_level = 0;
+}
+
static int tmff2_upload(struct input_dev *dev,
struct ff_effect *effect, struct ff_effect *old)
{
@@ -385,10 +408,13 @@ static int tmff2_upload(struct input_dev *dev,
spin_lock(&tmff2->lock);
state->effect = *effect;
+ tmff2_rewrite_rumble(&state->effect);
if (old) {
- if (!test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags))
+ if (!test_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags)) {
state->old = *old;
+ tmff2_rewrite_rumble(&state->old);
+ }
__set_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags);
} else {
@@ -555,6 +581,18 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
for (i = 0; tmff2->supported_effects[i] >= 0; ++i)
__set_bit(tmff2->supported_effects[i], tmff2->input_dev->ffbit);
+ /* tell ffb subsystem that we want to handle our own rumble effects,
+ * this is a (maybe kind of silly) workaround to the ffb subsystem
+ * setting the direction of rumble to 0, which in our case means 0
+ * force. Instead, do exactly what the subsystem would do, but update
+ * the direction.
+ *
+ * It *might* be a good idea to change this in the subsystem proper, but
+ * I don't know if anyone relies on the rumble to be 0 degrees, consider
+ * this just a proof of concept for now */
+ if (test_bit(FF_PERIODIC, tmff2->input_dev->ffbit))
+ __set_bit(FF_RUMBLE, tmff2->input_dev->ffbit);
+
/* create actual ff device*/
if ((ret = input_ff_create(tmff2->input_dev, tmff2->max_effects))) {
hid_err(tmff2->hdev, "could not create input_ff\n");
diff --git a/src/tmt300rs/hid-tmt300rs.c b/src/tmt300rs/hid-tmt300rs.c
index 0d81655..9b5d22d 100644
--- a/src/tmt300rs/hid-tmt300rs.c
+++ b/src/tmt300rs/hid-tmt300rs.c
@@ -409,14 +409,20 @@ int t300rs_play_effect(void *data, struct tmff2_effect_state *state)
struct t300rs_device_entry *t300rs = data;
struct __packed t300rs_packet_play {
struct t300rs_packet_header header;
- uint8_t value;
+ uint8_t code;
+ uint16_t count;
} *play_packet = (struct t300rs_packet_play *)t300rs->send_buffer;
int ret;
t300rs_fill_header(&play_packet->header, state->effect.id, 0x89);
- play_packet->value = 0x01;
+ play_packet->code = 0x41;
+
+ if (state->count == 0 || state->count >= 65535)
+ play_packet->count = 0;
+ else
+ play_packet->count = cpu_to_le16(state->count);
ret = t300rs_send_int(t300rs);
if (ret)