diff options
-rw-r--r-- | drivers/hid/usbhid/hid-pidff.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index a01c1b2ab2f4..488e6a6a14a6 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -15,10 +15,9 @@ #include <linux/input.h> #include <linux/slab.h> #include <linux/usb.h> - #include <linux/hid.h> +#include <linux/minmax.h> -#include "usbhid.h" #define PID_EFFECTS_MAX 64 #define PID_INFINITE 0xffff @@ -188,6 +187,16 @@ struct pidff_device { }; /* + * Clamp value for a given field + */ +static s32 pidff_clamp(s32 i, struct hid_field *field) +{ + s32 clamped = clamp(i, field->logical_minimum, field->logical_maximum); + pr_debug("clamped from %d to %d", i, clamped); + return clamped; +} + +/* * Scale an unsigned value with range 0..max for the given field */ static int pidff_rescale(int i, int max, struct hid_field *field) @@ -361,7 +370,11 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_periodic[PID_OFFSET], effect->u.periodic.offset); pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); - pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; + + /* Clamp period to ensure the device can play the effect */ + pidff->set_periodic[PID_PERIOD].value[0] = + pidff_clamp(effect->u.periodic.period, + pidff->set_periodic[PID_PERIOD].field); hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC], HID_REQ_SET_REPORT); |