aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wood <gitsend@mungewell.org>2016-09-18 12:55:38 -0400
committerJiri Kosina <jkosina@suse.cz>2016-09-26 09:39:54 -0400
commitc832f86effbcf8833fc2c842aa501ce1eb4d0478 (patch)
tree51ed8b198c543e6ea7f2e22227bbd670d9665a15
parent961af46f8e2c7bf793352c11262fb37e87706921 (diff)
HID: hid-logitech: Add combined pedal support Logitech wheels
Add support for reporting a combined accelerator/brake axis for wheels which contain combined data in their HID stream. This includes DF, MOMO, MOMO2 and DFP. Signed-off-by: Simon Wood <simon@mungewell.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-lg.c12
-rw-r--r--drivers/hid/hid-lg4ff.c32
-rw-r--r--drivers/hid/hid-lg4ff.h4
3 files changed, 48 insertions, 0 deletions
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index feb2be71f77c..06f8a5e0fc8f 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -657,6 +657,17 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
657 return 0; 657 return 0;
658} 658}
659 659
660static int lg_raw_event(struct hid_device *hdev, struct hid_report *report,
661 u8 *rd, int size)
662{
663 struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
664
665 if (drv_data->quirks & LG_FF4)
666 return lg4ff_raw_event(hdev, report, rd, size, drv_data);
667
668 return 0;
669}
670
660static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) 671static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
661{ 672{
662 struct usb_interface *iface = to_usb_interface(hdev->dev.parent); 673 struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
@@ -830,6 +841,7 @@ static struct hid_driver lg_driver = {
830 .input_mapping = lg_input_mapping, 841 .input_mapping = lg_input_mapping,
831 .input_mapped = lg_input_mapped, 842 .input_mapped = lg_input_mapped,
832 .event = lg_event, 843 .event = lg_event,
844 .raw_event = lg_raw_event,
833 .probe = lg_probe, 845 .probe = lg_probe,
834 .remove = lg_remove, 846 .remove = lg_remove,
835}; 847};
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index ca31ce4d2c24..79d34c2f639b 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -329,6 +329,38 @@ int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
329 } 329 }
330} 330}
331 331
332int lg4ff_raw_event(struct hid_device *hdev, struct hid_report *report,
333 u8 *rd, int size, struct lg_drv_data *drv_data)
334{
335 struct lg4ff_device_entry *entry = drv_data->device_props;
336
337 if (!entry)
338 return 0;
339
340 /* adjust HID report present combined pedals data */
341 if (entry->wdata.combine) {
342 switch (entry->wdata.product_id) {
343 case USB_DEVICE_ID_LOGITECH_WHEEL:
344 rd[5] = rd[3];
345 rd[6] = 0x7F;
346 return 1;
347 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
348 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
349 rd[4] = rd[3];
350 rd[5] = 0x7F;
351 return 1;
352 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
353 rd[5] = rd[4];
354 rd[6] = 0x7F;
355 return 1;
356 default:
357 return 0;
358 }
359 }
360
361 return 0;
362}
363
332static void lg4ff_init_wheel_data(struct lg4ff_wheel_data * const wdata, const struct lg4ff_wheel *wheel, 364static void lg4ff_init_wheel_data(struct lg4ff_wheel_data * const wdata, const struct lg4ff_wheel *wheel,
333 const struct lg4ff_multimode_wheel *mmode_wheel, 365 const struct lg4ff_multimode_wheel *mmode_wheel,
334 const u16 real_product_id) 366 const u16 real_product_id)
diff --git a/drivers/hid/hid-lg4ff.h b/drivers/hid/hid-lg4ff.h
index 66201af44da3..de1f350e0bd3 100644
--- a/drivers/hid/hid-lg4ff.h
+++ b/drivers/hid/hid-lg4ff.h
@@ -6,11 +6,15 @@ extern int lg4ff_no_autoswitch; /* From hid-lg.c */
6 6
7int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 7int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
8 struct hid_usage *usage, s32 value, struct lg_drv_data *drv_data); 8 struct hid_usage *usage, s32 value, struct lg_drv_data *drv_data);
9int lg4ff_raw_event(struct hid_device *hdev, struct hid_report *report,
10 u8 *rd, int size, struct lg_drv_data *drv_data);
9int lg4ff_init(struct hid_device *hdev); 11int lg4ff_init(struct hid_device *hdev);
10int lg4ff_deinit(struct hid_device *hdev); 12int lg4ff_deinit(struct hid_device *hdev);
11#else 13#else
12static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field, 14static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
13 struct hid_usage *usage, s32 value, struct lg_drv_data *drv_data) { return 0; } 15 struct hid_usage *usage, s32 value, struct lg_drv_data *drv_data) { return 0; }
16static inline int lg4ff_raw_event(struct hid_device *hdev, struct hid_report *report,
17 u8 *rd, int size, struct lg_drv_data *drv_data) { return 0; }
14static inline int lg4ff_init(struct hid_device *hdev) { return -1; } 18static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
15static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; } 19static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; }
16#endif 20#endif