diff options
| -rw-r--r-- | drivers/hid/usbhid/hid-pidff.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 50a8924edfcc..0342c0a3f476 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -184,6 +184,12 @@ struct pidff_usage { s32 *value; }; +struct pidff_effect { + int pid_id; + int is_infinite; + unsigned int loop_count; +}; + struct pidff_device { struct hid_device *hid; @@ -202,6 +208,8 @@ struct pidff_device { struct pidff_usage effect_operation[ARRAY_SIZE(pidff_effect_operation)]; struct pidff_usage block_free[ARRAY_SIZE(pidff_block_free)]; + struct pidff_effect effect[PID_EFFECTS_MAX]; + /* * Special field is a field that is not composed of * usage<->value pairs that pidff_usage values are @@ -230,8 +238,6 @@ struct pidff_device { int operation_id[ARRAY_SIZE(pidff_effect_operation_status)]; int direction_axis_id[ARRAY_SIZE(pidff_direction_axis)]; - int pid_id[PID_EFFECTS_MAX]; - u32 quirks; u8 effect_count; u8 axis_count; @@ -798,6 +804,12 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) return -EIO; } +static int pidff_needs_playback(struct pidff_device *pidff, int effect_id, int n) +{ + return pidff->effect[effect_id].is_infinite || + pidff->effect[effect_id].loop_count != n; +} + /* * Play the effect with PID id n times */ @@ -829,9 +841,14 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value) { struct pidff_device *pidff = dev->ff->private; + if (!pidff_needs_playback(pidff, effect_id, value)) + return 0; + hid_dbg(pidff->hid, "requesting %s on FF effect %d", value == 0 ? "stop" : "playback", effect_id); - pidff_playback_pid(pidff, pidff->pid_id[effect_id], value); + + pidff->effect[effect_id].loop_count = value; + pidff_playback_pid(pidff, pidff->effect[effect_id].pid_id, value); return 0; } @@ -852,10 +869,9 @@ static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) static int pidff_erase_effect(struct input_dev *dev, int effect_id) { struct pidff_device *pidff = dev->ff->private; - int pid_id = pidff->pid_id[effect_id]; + int pid_id = pidff->effect[effect_id].pid_id; - hid_dbg(pidff->hid, "starting to erase %d/%d\n", effect_id, - pidff->pid_id[effect_id]); + hid_dbg(pidff->hid, "starting to erase %d/%d\n", effect_id, pid_id); /* * Wait for the queue to clear. We do not want @@ -906,12 +922,16 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *new, pidff->effect_count++; hid_dbg(pidff->hid, "current effect count: %d", pidff->effect_count); - pidff->pid_id[new->id] = + pidff->effect[new->id].loop_count = 0; + pidff->effect[new->id].pid_id = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; } + pidff->effect[new->id].is_infinite = + pidff_is_duration_infinite(new->replay.length); + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = - pidff->pid_id[new->id]; + pidff->effect[new->id].pid_id; PIDFF_SET_REPORT_IF_NEEDED(effect, new, old); switch (new->type) { |
