Commit 13120abd authored by Tomasz Pakuła's avatar Tomasz Pakuła Committed by Jiri Kosina
Browse files

HID: pidff: Reduce PID_EFFECT_OPERATION spam



Keep track of effect's loop_count to reduce the spam of ffb play
commands coming from some games. This should speed up normal magnitude
etc updates and slightly increase max possible FFB refresh rate.

Helps games like Dirt Rally 2.0, F1 2023, WRC from KT

Signed-off-by: default avatarTomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.com>
parent 5b9cae8c
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -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) {