Skip to content

Commit f538183

Browse files
LawstorantJiri Kosina
authored andcommitted
HID: pidff: Clamp PERIODIC effect period to device's logical range
This ensures the effect can actually be played on the connected force feedback device. Adds clamping functions used instead of rescaling, as we don't want to change the characteristics of the periodic effects. Fixes edge cases found on Moza Racing and some other hardware where the effects would not play if the period is outside the defined logical range. Changes in v6: - Use in-kernel clamp macro instead of a custom solution Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> Reviewed-by: Michał Kopeć <michal@nozomi.space> Reviewed-by: Paul Dino Jones <paul@spacefreak18.xyz> Tested-by: Paul Dino Jones <paul@spacefreak18.xyz> Tested-by: Cristóferson Bueno <cbueno81@gmail.com> Tested-by: Pablo Cisneros <patchkez@protonmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 8876fc1 commit f538183

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

drivers/hid/usbhid/hid-pidff.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
#include <linux/input.h>
1616
#include <linux/slab.h>
1717
#include <linux/usb.h>
18-
1918
#include <linux/hid.h>
19+
#include <linux/minmax.h>
2020

21-
#include "usbhid.h"
2221

2322
#define PID_EFFECTS_MAX 64
2423
#define PID_INFINITE 0xffff
@@ -187,6 +186,16 @@ struct pidff_device {
187186
int pid_id[PID_EFFECTS_MAX];
188187
};
189188

189+
/*
190+
* Clamp value for a given field
191+
*/
192+
static s32 pidff_clamp(s32 i, struct hid_field *field)
193+
{
194+
s32 clamped = clamp(i, field->logical_minimum, field->logical_maximum);
195+
pr_debug("clamped from %d to %d", i, clamped);
196+
return clamped;
197+
}
198+
190199
/*
191200
* Scale an unsigned value with range 0..max for the given field
192201
*/
@@ -361,7 +370,11 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
361370
pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
362371
effect->u.periodic.offset);
363372
pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
364-
pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
373+
374+
/* Clamp period to ensure the device can play the effect */
375+
pidff->set_periodic[PID_PERIOD].value[0] =
376+
pidff_clamp(effect->u.periodic.period,
377+
pidff->set_periodic[PID_PERIOD].field);
365378

366379
hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC],
367380
HID_REQ_SET_REPORT);

0 commit comments

Comments
 (0)