Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: Autocentering support for Logitech MOMO Racing Wheel

Current kernel has no support for autocentering for Logitech wheels. By
default autocentering enabled in wheel and constant effect does not work
properly. Using USB sniffer I found command which change autocentering
settings: 0xFE, 0x0D, 0x0R, 0x0L, 0x80, 0x00, 0x00, where R - clockwise force,
L - counter-clockwise (0x0-0xF, 0xC = 100%).

Signed-off-by: Sergey Belyashov <Sergey.Belyashov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Sergey Belyashov and committed by
Jiri Kosina
2bea94db 6f3c0e50

+27 -1
+27 -1
drivers/hid/hid-lgff.c
··· 50 50 -1 51 51 }; 52 52 53 + static const signed short ff_wheel[] = { 54 + FF_CONSTANT, 55 + FF_AUTOCENTER, 56 + -1 57 + }; 58 + 53 59 static const struct dev_type devices[] = { 54 60 { 0x046d, 0xc211, ff_rumble }, 55 61 { 0x046d, 0xc219, ff_rumble }, ··· 63 57 { 0x046d, 0xc286, ff_joystick }, 64 58 { 0x046d, 0xc294, ff_joystick }, 65 59 { 0x046d, 0xc295, ff_joystick }, 66 - { 0x046d, 0xca03, ff_joystick }, 60 + { 0x046d, 0xca03, ff_wheel }, 67 61 }; 68 62 69 63 static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect) ··· 106 100 break; 107 101 } 108 102 return 0; 103 + } 104 + 105 + static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) 106 + { 107 + struct hid_device *hid = input_get_drvdata(dev); 108 + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; 109 + struct hid_report *report = list_entry(report_list->next, struct hid_report, list); 110 + __s32 *value = report->field[0]->value; 111 + magnitude = (magnitude >> 12) & 0xf; 112 + *value++ = 0xfe; 113 + *value++ = 0x0d; 114 + *value++ = magnitude; /* clockwise strength */ 115 + *value++ = magnitude; /* counter-clockwise strength */ 116 + *value++ = 0x80; 117 + *value++ = 0x00; 118 + *value = 0x00; 119 + usbhid_submit_report(hid, report, USB_DIR_OUT); 109 120 } 110 121 111 122 int lgff_init(struct hid_device* hid) ··· 169 146 error = input_ff_create_memless(dev, NULL, hid_lgff_play); 170 147 if (error) 171 148 return error; 149 + 150 + if ( test_bit(FF_AUTOCENTER, dev->ffbit) ) 151 + dev->ff->set_autocenter = hid_lgff_set_autocenter; 172 152 173 153 printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n"); 174 154