Commit 85cbea39 authored by Jiri Kosina's avatar Jiri Kosina

USB HID: Logitech MX3000 keyboard needs report descriptor quirk

Logitech MX3000 contains report descriptor which doesn't cover usages
above 0x28c, but emits such usages. Report descriptor needs fixing
in the very same way as with receivers shipped with S510 keyboards.

This patch also adds a few mappings for multimedia keys that S510 didn't
emit.
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent bf892e60
...@@ -540,10 +540,26 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel ...@@ -540,10 +540,26 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x302: map_key_clear(KEY_PROG2); break; case 0x302: map_key_clear(KEY_PROG2); break;
case 0x303: map_key_clear(KEY_PROG3); break; case 0x303: map_key_clear(KEY_PROG3); break;
/* Reported on Logitech S510 wireless keyboard */ /* Reported on certain Logitech wireless keyboards */
case 0x1001: map_key_clear(KEY_MESSENGER); break;
case 0x1003: map_key_clear(KEY_SOUND); break;
case 0x1004: map_key_clear(KEY_VIDEO); break;
case 0x1005: map_key_clear(KEY_AUDIO); break;
case 0x100a: map_key_clear(KEY_DOCUMENTS); break;
case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break;
case 0x1012: map_key_clear(KEY_NEXTSONG); break;
case 0x1013: map_key_clear(KEY_CAMERA); break;
case 0x1014: map_key_clear(KEY_MESSENGER); break;
case 0x1015: map_key_clear(KEY_RECORD); break;
case 0x1016: map_key_clear(KEY_PLAYER); break;
case 0x1017: map_key_clear(KEY_EJECTCD); break;
case 0x1019: map_key_clear(KEY_PROG1); break;
case 0x101a: map_key_clear(KEY_PROG2); break;
case 0x101b: map_key_clear(KEY_PROG3); break;
case 0x101f: map_key_clear(KEY_ZOOMIN); break; case 0x101f: map_key_clear(KEY_ZOOMIN); break;
case 0x1020: map_key_clear(KEY_ZOOMOUT); break; case 0x1020: map_key_clear(KEY_ZOOMOUT); break;
case 0x1021: map_key_clear(KEY_ZOOMRESET); break; case 0x1021: map_key_clear(KEY_ZOOMRESET); break;
case 0x1023: map_key_clear(KEY_CLOSE); break;
/* this one is marked as 'Rotate' */ /* this one is marked as 'Rotate' */
case 0x1028: map_key_clear(KEY_ANGLE); break; case 0x1028: map_key_clear(KEY_ANGLE); break;
case 0x1029: map_key_clear(KEY_SHUFFLE); break; case 0x1029: map_key_clear(KEY_SHUFFLE); break;
......
...@@ -225,9 +225,10 @@ MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); ...@@ -225,9 +225,10 @@ MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 #define USB_DEVICE_ID_LD_MACHINETEST 0x2040
#define USB_VENDOR_ID_LOGITECH 0x046d #define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_S510_USB_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER 0xc50c
#define USB_DEVICE_ID_S510_USB_RECEIVER_2 0xc517 #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 #define USB_DEVICE_ID_DINOVO_EDGE 0xc714
#define USB_VENDOR_ID_MCC 0x09db #define USB_VENDOR_ID_MCC 0x09db
...@@ -297,7 +298,7 @@ static const struct hid_blacklist { ...@@ -297,7 +298,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
...@@ -434,8 +435,9 @@ static const struct hid_blacklist { ...@@ -434,8 +435,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_USB_RECEIVER, HID_QUIRK_LOGITECH_S510_DESCRIPTOR }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_USB_RECEIVER_2, HID_QUIRK_LOGITECH_S510_DESCRIPTOR }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_LOGITECH_DESCRIPTOR },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
...@@ -1049,16 +1051,16 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) ...@@ -1049,16 +1051,16 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
} }
/* /*
* Logitech S510 keyboard sends in report #3 keys which are far * Certain Logitech keyboards send in report #3 keys which are far
* above the logical maximum described in descriptor. This extends * above the logical maximum described in descriptor. This extends
* the original value of 0x28c of logical maximum to 0x104d * the original value of 0x28c of logical maximum to 0x104d
*/ */
static void hid_fixup_s510_descriptor(unsigned char *rdesc, int rsize) static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
{ {
if (rsize >= 90 && rdesc[83] == 0x26 if (rsize >= 90 && rdesc[83] == 0x26
&& rdesc[84] == 0x8c && rdesc[84] == 0x8c
&& rdesc[85] == 0x02) { && rdesc[85] == 0x02) {
info("Fixing up Logitech S510 report descriptor"); info("Fixing up Logitech keyboard report descriptor");
rdesc[84] = rdesc[89] = 0x4d; rdesc[84] = rdesc[89] = 0x4d;
rdesc[85] = rdesc[90] = 0x10; rdesc[85] = rdesc[90] = 0x10;
} }
...@@ -1138,8 +1140,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) ...@@ -1138,8 +1140,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if ((quirks & HID_QUIRK_CYMOTION)) if ((quirks & HID_QUIRK_CYMOTION))
hid_fixup_cymotion_descriptor(rdesc, rsize); hid_fixup_cymotion_descriptor(rdesc, rsize);
if (quirks & HID_QUIRK_LOGITECH_S510_DESCRIPTOR) if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
hid_fixup_s510_descriptor(rdesc, rsize); hid_fixup_logitech_descriptor(rdesc, rsize);
#ifdef CONFIG_HID_DEBUG #ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
......
...@@ -267,7 +267,7 @@ struct hid_item { ...@@ -267,7 +267,7 @@ struct hid_item {
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000
#define HID_QUIRK_IGNORE_MOUSE 0x00040000 #define HID_QUIRK_IGNORE_MOUSE 0x00040000
#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000
#define HID_QUIRK_LOGITECH_S510_DESCRIPTOR 0x00100000 #define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 #define HID_QUIRK_DUPLICATE_USAGES 0x00200000
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment