···1136411364F: drivers/iio/*/hid-*1136511365F: include/linux/hid-sensor-*11366113661136711367-HID UNIVERSAL PIDFF DRIVER1136811368-M: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>1136911369-M: Oleg Makarenko <oleg@makarenk.ooo>1137011370-L: linux-input@vger.kernel.org1137111371-S: Maintained1137211372-B: https://github.com/JacKeTUs/universal-pidff/issues1137311373-F: drivers/hid/hid-universal-pidff.c1137411374-1137511367HID VRC-2 CAR CONTROLLER DRIVER1137611368M: Marcus Folkesson <marcus.folkesson@gmail.com>1137711369L: linux-input@vger.kernel.org···2727027278T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git2727127279F: Documentation/hid/hiddev.rst2727227280F: drivers/hid/usbhid/2728127281+2728227282+USB HID PID DRIVERS (USB WHEELBASES, JOYSTICKS, RUDDERS, ...)2728327283+M: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>2728427284+M: Oleg Makarenko <oleg@makarenk.ooo>2728527285+L: linux-input@vger.kernel.org2728627286+S: Maintained2728727287+B: https://github.com/JacKeTUs/universal-pidff/issues2728827288+F: drivers/hid/usbhid/hid-pidff*2728927289+F: drivers/hid/hid-universal-pidff.c27273272902727427291USB INTEL XHCI ROLE MUX DRIVER2727527292M: Hans de Goede <hansg@kernel.org>
+38-19
drivers/hid/usbhid/hid-pidff.c
···1313#include <linux/input.h>1414#include <linux/minmax.h>1515#include <linux/slab.h>1616+#include <linux/stringify.h>1617#include <linux/usb.h>17181819#define PID_EFFECTS_MAX 64···8281#define PID_NEG_COEFFICIENT 48382#define PID_POS_SATURATION 58483#define PID_NEG_SATURATION 68585-#define PID_DEAD_BAND 78484+#define PID_DEADBAND 78685static const u8 pidff_set_condition[] = {8786 0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x658887};···619618 effect->u.condition[i].center);620619 pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],621620 effect->u.condition[i].right_coeff);622622- pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],623623- effect->u.condition[i].left_coeff);624621 pidff_set(&pidff->set_condition[PID_POS_SATURATION],625622 effect->u.condition[i].right_saturation);626626- pidff_set(&pidff->set_condition[PID_NEG_SATURATION],627627- effect->u.condition[i].left_saturation);628628- pidff_set(&pidff->set_condition[PID_DEAD_BAND],629629- effect->u.condition[i].deadband);623623+624624+ /* Omit Negative Coefficient if missing */625625+ if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_NEG_COEFFICIENT))626626+ pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],627627+ effect->u.condition[i].left_coeff);628628+629629+ /* Omit Negative Saturation if missing */630630+ if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_NEG_SATURATION))631631+ pidff_set_signed(&pidff->set_condition[PID_NEG_SATURATION],632632+ effect->u.condition[i].left_saturation);633633+634634+ /* Omit Deadband field if missing */635635+ if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DEADBAND))636636+ pidff_set(&pidff->set_condition[PID_DEADBAND],637637+ effect->u.condition[i].deadband);638638+630639 hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONDITION],631640 HID_REQ_SET_REPORT);632641 }···10641053 return -1;10651054}1066105510561056+#define PIDFF_MISSING_FIELD(name, quirks) \10571057+ ({ pr_debug("%s field not found, but that's OK\n", __stringify(name)); \10581058+ pr_debug("Setting MISSING_%s quirk\n", __stringify(name)); \10591059+ *quirks |= HID_PIDFF_QUIRK_MISSING_ ## name; })10601060+10671061/*10681062 * Find fields from a report and fill a pidff_usage10691063 */···10761060 struct hid_report *report, int count, int strict,10771061 u32 *quirks)10781062{10791079- const u8 block_offset = pidff_set_condition[PID_PARAM_BLOCK_OFFSET];10801080- const u8 delay = pidff_set_effect[PID_START_DELAY];10811081-10821063 if (!report) {10831064 pr_debug("%s, null report\n", __func__);10841065 return -1;···10931080 continue;10941081 }1095108210961096- if (table[i] == delay) {10971097- pr_debug("Delay field not found, but that's OK\n");10981098- pr_debug("Setting MISSING_DELAY quirk\n");10991099- *quirks |= HID_PIDFF_QUIRK_MISSING_DELAY;10831083+ /* Field quirks auto-detection */10841084+ if (table[i] == pidff_set_effect[PID_START_DELAY])10851085+ PIDFF_MISSING_FIELD(DELAY, quirks);1100108611011101- } else if (table[i] == block_offset) {11021102- pr_debug("PBO field not found, but that's OK\n");11031103- pr_debug("Setting MISSING_PBO quirk\n");11041104- *quirks |= HID_PIDFF_QUIRK_MISSING_PBO;10871087+ else if (table[i] == pidff_set_condition[PID_PARAM_BLOCK_OFFSET])10881088+ PIDFF_MISSING_FIELD(PBO, quirks);1105108911061106- } else if (strict) {10901090+ else if (table[i] == pidff_set_condition[PID_NEG_COEFFICIENT])10911091+ PIDFF_MISSING_FIELD(NEG_COEFFICIENT, quirks);10921092+10931093+ else if (table[i] == pidff_set_condition[PID_NEG_SATURATION])10941094+ PIDFF_MISSING_FIELD(NEG_SATURATION, quirks);10951095+10961096+ else if (table[i] == pidff_set_condition[PID_DEADBAND])10971097+ PIDFF_MISSING_FIELD(DEADBAND, quirks);10981098+10991099+ else if (strict) {11071100 pr_debug("failed to locate %d\n", i);11081101 return -1;11091102 }
+9
drivers/hid/usbhid/hid-pidff.h
···2121/* Force all periodic effects to be uploaded as SINE */2222#define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY BIT(4)23232424+/* Allow devices with missing negative coefficient in the set condition usage */2525+#define HID_PIDFF_QUIRK_MISSING_NEG_COEFFICIENT BIT(5)2626+2727+/* Allow devices with missing negative saturation in the set condition usage */2828+#define HID_PIDFF_QUIRK_MISSING_NEG_SATURATION BIT(6)2929+3030+/* Allow devices with missing deadband in the set condition usage */3131+#define HID_PIDFF_QUIRK_MISSING_DEADBAND BIT(7)3232+2433#ifdef CONFIG_HID_PID2534int hid_pidff_init(struct hid_device *hid);2635int hid_pidff_init_with_quirks(struct hid_device *hid, u32 initial_quirks);