diff options
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 45 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
2 files changed, 46 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 762cb35e769b..cec3bffa0a9a 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -129,6 +129,9 @@ MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | |||
129 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 129 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
130 | #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 | 130 | #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 |
131 | 131 | ||
132 | #define USB_VENDOR_ID_DELL 0x413c | ||
133 | #define USB_DEVICE_ID_DELL_W7658 0x2005 | ||
134 | |||
132 | #define USB_VENDOR_ID_DELORME 0x1163 | 135 | #define USB_VENDOR_ID_DELORME 0x1163 |
133 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 136 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
134 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | 137 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 |
@@ -469,6 +472,8 @@ static const struct hid_blacklist { | |||
469 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 472 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
470 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 473 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
471 | 474 | ||
475 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, | ||
476 | |||
472 | { 0, 0 } | 477 | { 0, 0 } |
473 | }; | 478 | }; |
474 | 479 | ||
@@ -964,6 +969,44 @@ void usbhid_init_reports(struct hid_device *hid) | |||
964 | } | 969 | } |
965 | 970 | ||
966 | /* | 971 | /* |
972 | * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01). | ||
973 | */ | ||
974 | static int hid_find_field_early(struct hid_device *hid, unsigned int page, | ||
975 | unsigned int hid_code, struct hid_field **pfield) | ||
976 | { | ||
977 | struct hid_report *report; | ||
978 | struct hid_field *field; | ||
979 | struct hid_usage *usage; | ||
980 | int i, j; | ||
981 | |||
982 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { | ||
983 | for (i = 0; i < report->maxfield; i++) { | ||
984 | field = report->field[i]; | ||
985 | for (j = 0; j < field->maxusage; j++) { | ||
986 | usage = &field->usage[j]; | ||
987 | if ((usage->hid & HID_USAGE_PAGE) == page && | ||
988 | (usage->hid & 0xFFFF) == hid_code) { | ||
989 | *pfield = field; | ||
990 | return j; | ||
991 | } | ||
992 | } | ||
993 | } | ||
994 | } | ||
995 | return -1; | ||
996 | } | ||
997 | |||
998 | static void usbhid_set_leds(struct hid_device *hid) | ||
999 | { | ||
1000 | struct hid_field *field; | ||
1001 | int offset; | ||
1002 | |||
1003 | if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) { | ||
1004 | hid_set_field(field, offset, 0); | ||
1005 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); | ||
1006 | } | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
967 | * Traverse the supplied list of reports and find the longest | 1010 | * Traverse the supplied list of reports and find the longest |
968 | */ | 1011 | */ |
969 | static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) | 1012 | static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) |
@@ -1348,6 +1391,8 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1348 | 1391 | ||
1349 | usbhid_init_reports(hid); | 1392 | usbhid_init_reports(hid); |
1350 | hid_dump_device(hid); | 1393 | hid_dump_device(hid); |
1394 | if (hid->quirks & HID_QUIRK_RESET_LEDS) | ||
1395 | usbhid_set_leds(hid); | ||
1351 | 1396 | ||
1352 | if (!hidinput_connect(hid)) | 1397 | if (!hidinput_connect(hid)) |
1353 | hid->claimed |= HID_CLAIMED_INPUT; | 1398 | hid->claimed |= HID_CLAIMED_INPUT; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 55184415fd6b..d73b24b1e265 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -269,6 +269,7 @@ struct hid_item { | |||
269 | #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 | 269 | #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 |
270 | #define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 | 270 | #define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 |
271 | #define HID_QUIRK_DUPLICATE_USAGES 0x00200000 | 271 | #define HID_QUIRK_DUPLICATE_USAGES 0x00200000 |
272 | #define HID_QUIRK_RESET_LEDS 0x00400000 | ||
272 | 273 | ||
273 | /* | 274 | /* |
274 | * This is the global environment of the parser. This information is | 275 | * This is the global environment of the parser. This information is |