Skip to content

Commit 2d5c7ce

Browse files
LawstorantJiri Kosina
authored andcommitted
HID: pidff: Add MISSING_DELAY quirk and its detection
A lot of devices do not include this field, and it's seldom used in force feedback implementations. I tested about three dozen applications and none of them make use of the delay. This fixes initialization of a lot of PID wheels like Cammus, VRS, FFBeast This change has no effect on fully compliant devices Co-developed-by: Makarenko Oleg <oleg@makarenk.ooo> Signed-off-by: Makarenko Oleg <oleg@makarenk.ooo> 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 f538183 commit 2d5c7ce

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

drivers/hid/usbhid/hid-pidff.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ struct pidff_device {
184184
int operation_id[sizeof(pidff_effect_operation_status)];
185185

186186
int pid_id[PID_EFFECTS_MAX];
187+
188+
u32 quirks;
187189
};
188190

189191
/*
@@ -338,7 +340,10 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
338340
pidff->effect_direction->value[0] =
339341
pidff_rescale(effect->direction, 0xffff,
340342
pidff->effect_direction);
341-
pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
343+
344+
/* Omit setting delay field if it's missing */
345+
if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))
346+
pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
342347

343348
hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT],
344349
HID_REQ_SET_REPORT);
@@ -761,7 +766,10 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
761766
pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
762767
pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
763768
pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
764-
pidff->set_effect[PID_START_DELAY].value[0] = 0;
769+
770+
/* Omit setting delay field if it's missing */
771+
if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))
772+
pidff->set_effect[PID_START_DELAY].value[0] = 0;
765773

766774
hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT],
767775
HID_REQ_SET_REPORT);
@@ -784,6 +792,7 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
784792
struct hid_report *report, int count, int strict)
785793
{
786794
int i, j, k, found;
795+
int return_value = 0;
787796

788797
for (k = 0; k < count; k++) {
789798
found = 0;
@@ -808,12 +817,17 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
808817
if (found)
809818
break;
810819
}
811-
if (!found && strict) {
820+
if (!found && table[k] == pidff_set_effect[PID_START_DELAY]) {
821+
pr_debug("Delay field not found, but that's OK\n");
822+
pr_debug("Setting MISSING_DELAY quirk\n");
823+
return_value |= HID_PIDFF_QUIRK_MISSING_DELAY;
824+
}
825+
else if (!found && strict) {
812826
pr_debug("failed to locate %d\n", k);
813827
return -1;
814828
}
815829
}
816-
return 0;
830+
return return_value;
817831
}
818832

819833
/*
@@ -1088,11 +1102,19 @@ static int pidff_find_effects(struct pidff_device *pidff,
10881102
static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
10891103
{
10901104
int envelope_ok = 0;
1105+
int status = 0;
10911106

1092-
if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
1107+
/* Save info about the device not having the DELAY ffb field. */
1108+
status = PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1);
1109+
if (status == -1) {
10931110
hid_err(pidff->hid, "unknown set_effect report layout\n");
10941111
return -ENODEV;
10951112
}
1113+
pidff->quirks |= status;
1114+
1115+
if (status & HID_PIDFF_QUIRK_MISSING_DELAY)
1116+
hid_dbg(pidff->hid, "Adding MISSING_DELAY quirk\n");
1117+
10961118

10971119
PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
10981120
if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
@@ -1336,6 +1358,7 @@ int hid_pidff_init(struct hid_device *hid)
13361358
ff->playback = pidff_playback;
13371359

13381360
hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
1361+
hid_dbg(dev, "Active quirks mask: 0x%x\n", pidff->quirks);
13391362

13401363
hid_device_io_stop(hid);
13411364

include/linux/hid.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,9 @@ int hid_pidff_init(struct hid_device *hid);
12281228
#define hid_pidff_init NULL
12291229
#endif
12301230

1231+
/* HID PIDFF quirks */
1232+
#define HID_PIDFF_QUIRK_MISSING_DELAY BIT(0)
1233+
12311234
#define dbg_hid(fmt, ...) pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__)
12321235

12331236
#define hid_err(hid, fmt, ...) \

0 commit comments

Comments
 (0)