summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-input.c15
-rw-r--r--drivers/usb/input/hid-core.c3
-rw-r--r--include/linux/hid.h1
3 files changed, 14 insertions, 5 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index eeba66513997..c8434023ba65 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -71,7 +71,6 @@ static const struct {
 #define map_led(c)	do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
 
 #define map_abs_clear(c)	do { map_abs(c); clear_bit(c, bit); } while (0)
-#define map_rel_clear(c)	do { map_rel(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)	do { map_key(c); clear_bit(c, bit); } while (0)
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
@@ -296,7 +295,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 					}
 			}
 
-			map_key_clear(code);
+			map_key(code);
 			break;
 
 
@@ -347,9 +346,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 				case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
 				case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
 					if (field->flags & HID_MAIN_ITEM_RELATIVE)
-						map_rel_clear(usage->hid & 0xf);
+						map_rel(usage->hid & 0xf);
 					else
-						map_abs_clear(usage->hid & 0xf);
+						map_abs(usage->hid & 0xf);
 					break;
 
 				case HID_GD_HATSWITCH:
@@ -519,7 +518,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 				case 0x22f: map_key_clear(KEY_ZOOMRESET);	break;
 				case 0x233: map_key_clear(KEY_SCROLLUP);	break;
 				case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
-				case 0x238: map_rel_clear(REL_HWHEEL);		break;
+				case 0x238: map_rel(REL_HWHEEL);		break;
 				case 0x25f: map_key_clear(KEY_CANCEL);		break;
 				case 0x279: map_key_clear(KEY_REDO);		break;
 
@@ -667,6 +666,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
 	set_bit(usage->type, input->evbit);
 
+	if (device->quirks & HID_QUIRK_DUPLICATE_USAGES &&
+			(usage->type == EV_KEY ||
+			 usage->type == EV_REL ||
+			 usage->type == EV_ABS))
+		clear_bit(usage->code, bit);
+
 	while (usage->code <= max && test_and_set_bit(usage->code, bit))
 		usage->code = find_next_zero_bit(bit, max + 1, usage->code);
 
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 5d5221324e63..12ec8b432953 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -756,6 +756,7 @@ void usbhid_init_reports(struct hid_device *hid)
 #define USB_VENDOR_ID_LOGITECH		0x046d
 #define USB_DEVICE_ID_LOGITECH_USB_RECEIVER	0xc101
 #define USB_DEVICE_ID_LOGITECH_USB_RECEIVER_2	0xc517
+#define USB_DEVICE_ID_DINOVO_EDGE	0xc714
 
 #define USB_VENDOR_ID_IMATION		0x0718
 #define USB_DEVICE_ID_DISC_STAKKA	0xd000
@@ -776,6 +777,8 @@ static const struct hid_blacklist {
 	unsigned quirks;
 } hid_blacklist[] = {
 
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
+
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index b08ad8a23699..8c97d4d3fdb0 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -268,6 +268,7 @@ struct hid_item {
 #define HID_QUIRK_IGNORE_MOUSE			0x00040000
 #define HID_QUIRK_SONY_PS3_CONTROLLER		0x00080000
 #define HID_QUIRK_LOGITECH_S510_DESCRIPTOR	0x00100000
+#define HID_QUIRK_DUPLICATE_USAGES		0x00200000
 
 /*
  * This is the global environment of the parser. This information is