aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-lg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-lg.c')
-rw-r--r--drivers/hid/hid-lg.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 0f870a3243ed..9fcd3d017ab3 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -33,6 +33,7 @@
33#define LG_NOGET 0x100 33#define LG_NOGET 0x100
34#define LG_FF 0x200 34#define LG_FF 0x200
35#define LG_FF2 0x400 35#define LG_FF2 0x400
36#define LG_RDESC_REL_ABS 0x800
36 37
37/* 38/*
38 * Certain Logitech keyboards send in report #3 keys which are far 39 * Certain Logitech keyboards send in report #3 keys which are far
@@ -51,6 +52,13 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
51 rdesc[84] = rdesc[89] = 0x4d; 52 rdesc[84] = rdesc[89] = 0x4d;
52 rdesc[85] = rdesc[90] = 0x10; 53 rdesc[85] = rdesc[90] = 0x10;
53 } 54 }
55 if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
56 rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
57 rdesc[49] == 0x81 && rdesc[50] == 0x06) {
58 dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
59 "report descriptor\n");
60 rdesc[33] = rdesc[50] = 0x02;
61 }
54} 62}
55 63
56#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 64#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
@@ -89,6 +97,22 @@ static int lg_ultrax_remote_mapping(struct hid_input *hi,
89 return 1; 97 return 1;
90} 98}
91 99
100static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
101 unsigned long **bit, int *max)
102{
103 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
104 return 0;
105
106 switch (usage->hid & HID_USAGE) {
107
108 case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
109 default:
110 return 0;
111
112 }
113 return 1;
114}
115
92static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage, 116static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
93 unsigned long **bit, int *max) 117 unsigned long **bit, int *max)
94{ 118{
@@ -164,6 +188,10 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
164 lg_ultrax_remote_mapping(hi, usage, bit, max)) 188 lg_ultrax_remote_mapping(hi, usage, bit, max))
165 return 1; 189 return 1;
166 190
191 if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
192 lg_dinovo_mapping(hi, usage, bit, max))
193 return 1;
194
167 if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) 195 if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
168 return 1; 196 return 1;
169 197
@@ -303,8 +331,13 @@ static const struct hid_device_id lg_devices[] = {
303 .driver_data = LG_FF }, 331 .driver_data = LG_FF },
304 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), 332 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
305 .driver_data = LG_FF2 }, 333 .driver_data = LG_FF2 },
334 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
335 .driver_data = LG_RDESC_REL_ABS },
336 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
337 .driver_data = LG_RDESC_REL_ABS },
306 { } 338 { }
307}; 339};
340
308MODULE_DEVICE_TABLE(hid, lg_devices); 341MODULE_DEVICE_TABLE(hid, lg_devices);
309 342
310static struct hid_driver lg_driver = { 343static struct hid_driver lg_driver = {