aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-05-19 08:04:49 -0400
committerJiri Kosina <jkosina@suse.cz>2010-05-19 08:04:49 -0400
commit7426ef52b42ebd54ba85133ffd29132e008a882c (patch)
tree5232ca850065baf025e8d7384408b48b4b462c96
parent537b60d17894b7c19a6060feae40299d7109d6e7 (diff)
parenta8ab5d58b0238b8199cc699b8dff7c5e1da24138 (diff)
Merge branch 'upstream' into for-linus
Conflicts: drivers/hid/hid-wacom.c
-rw-r--r--Documentation/ABI/testing/sysfs-wacom10
-rw-r--r--drivers/hid/Kconfig19
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-3m-pct.c31
-rw-r--r--drivers/hid/hid-core.c23
-rw-r--r--drivers/hid/hid-ids.h12
-rw-r--r--drivers/hid/hid-lg.c9
-rw-r--r--drivers/hid/hid-samsung.c95
-rw-r--r--drivers/hid/hid-topseed.c38
-rw-r--r--drivers/hid/hid-wacom.c229
-rw-r--r--drivers/hid/hid-zydacron.c237
-rw-r--r--drivers/hid/hidraw.c2
-rw-r--r--drivers/hid/usbhid/hid-core.c48
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
-rw-r--r--drivers/hid/usbhid/usbkbd.c1
-rw-r--r--include/linux/hid.h2
16 files changed, 679 insertions, 79 deletions
diff --git a/Documentation/ABI/testing/sysfs-wacom b/Documentation/ABI/testing/sysfs-wacom
new file mode 100644
index 000000000000..1517976e25c4
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-wacom
@@ -0,0 +1,10 @@
1What: /sys/class/hidraw/hidraw*/device/speed
2Date: April 2010
3Kernel Version: 2.6.35
4Contact: linux-bluetooth@vger.kernel.org
5Description:
6 The /sys/class/hidraw/hidraw*/device/speed file controls
7 reporting speed of wacom bluetooth tablet. Reading from
8 this file returns 1 if tablet reports in high speed mode
9 or 0 otherwise. Writing to this file one of these values
10 switches reporting speed.
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 71d4c0703629..ac8e12d00c0f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -273,7 +273,7 @@ config HID_SAMSUNG
273 depends on USB_HID 273 depends on USB_HID
274 default !EMBEDDED 274 default !EMBEDDED
275 ---help--- 275 ---help---
276 Support for Samsung InfraRed remote control. 276 Support for Samsung InfraRed remote control or keyboards.
277 277
278config HID_SONY 278config HID_SONY
279 tristate "Sony" if EMBEDDED 279 tristate "Sony" if EMBEDDED
@@ -332,7 +332,7 @@ config HID_TOPSEED
332 depends on USB_HID 332 depends on USB_HID
333 default !EMBEDDED 333 default !EMBEDDED
334 ---help--- 334 ---help---
335 Say Y if you have a TopSeed Cyberlink remote control. 335 Say Y if you have a TopSeed Cyberlink or BTC Emprex remote control.
336 336
337config HID_THRUSTMASTER 337config HID_THRUSTMASTER
338 tristate "ThrustMaster devices support" if EMBEDDED 338 tristate "ThrustMaster devices support" if EMBEDDED
@@ -357,6 +357,14 @@ config HID_WACOM
357 ---help--- 357 ---help---
358 Support for Wacom Graphire Bluetooth tablet. 358 Support for Wacom Graphire Bluetooth tablet.
359 359
360config HID_WACOM_POWER_SUPPLY
361 bool "Wacom Bluetooth devices power supply status support"
362 depends on HID_WACOM
363 select POWER_SUPPLY
364 ---help---
365 Say Y here if you want to enable power supply status monitoring for
366 Wacom Bluetooth devices.
367
360config HID_ZEROPLUS 368config HID_ZEROPLUS
361 tristate "Zeroplus based game controller support" if EMBEDDED 369 tristate "Zeroplus based game controller support" if EMBEDDED
362 depends on USB_HID 370 depends on USB_HID
@@ -372,6 +380,13 @@ config ZEROPLUS_FF
372 Say Y here if you have a Zeroplus based game controller and want 380 Say Y here if you have a Zeroplus based game controller and want
373 to have force feedback support for it. 381 to have force feedback support for it.
374 382
383config HID_ZYDACRON
384 tristate "Zydacron remote control support" if EMBEDDED
385 depends on USB_HID
386 default !EMBEDDED
387 ---help---
388 Support for Zydacron remote control.
389
375endmenu 390endmenu
376 391
377endif # HID_SUPPORT 392endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 0b2618f092ca..d1f1b448977d 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
54obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o 54obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
55obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o 55obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
56obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o 56obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
57obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
57obj-$(CONFIG_HID_WACOM) += hid-wacom.o 58obj-$(CONFIG_HID_WACOM) += hid-wacom.o
58 59
59obj-$(CONFIG_USB_HID) += usbhid/ 60obj-$(CONFIG_USB_HID) += usbhid/
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index c31e0be8ccea..2a0d56b7a02b 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * HID driver for 3M PCT multitouch panels 2 * HID driver for 3M PCT multitouch panels
3 * 3 *
4 * Copyright (c) 2009 Stephane Chatty <chatty@enac.fr> 4 * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
5 * 5 *
6 */ 6 */
7 7
@@ -25,7 +25,7 @@ MODULE_LICENSE("GPL");
25#include "hid-ids.h" 25#include "hid-ids.h"
26 26
27struct mmm_finger { 27struct mmm_finger {
28 __s32 x, y; 28 __s32 x, y, w, h;
29 __u8 rank; 29 __u8 rank;
30 bool touch, valid; 30 bool touch, valid;
31}; 31};
@@ -82,7 +82,18 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
82 /* touchscreen emulation */ 82 /* touchscreen emulation */
83 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 83 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
84 return 1; 84 return 1;
85 case HID_DG_WIDTH:
86 hid_map_usage(hi, usage, bit, max,
87 EV_ABS, ABS_MT_TOUCH_MAJOR);
88 return 1;
89 case HID_DG_HEIGHT:
90 hid_map_usage(hi, usage, bit, max,
91 EV_ABS, ABS_MT_TOUCH_MINOR);
92 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
93 1, 1, 0, 0);
94 return 1;
85 case HID_DG_CONTACTID: 95 case HID_DG_CONTACTID:
96 field->logical_maximum = 59;
86 hid_map_usage(hi, usage, bit, max, 97 hid_map_usage(hi, usage, bit, max,
87 EV_ABS, ABS_MT_TRACKING_ID); 98 EV_ABS, ABS_MT_TRACKING_ID);
88 return 1; 99 return 1;
@@ -128,9 +139,15 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
128 /* this finger is just placeholder data, ignore */ 139 /* this finger is just placeholder data, ignore */
129 } else if (f->touch) { 140 } else if (f->touch) {
130 /* this finger is on the screen */ 141 /* this finger is on the screen */
142 int wide = (f->w > f->h);
131 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i); 143 input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i);
132 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); 144 input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
133 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); 145 input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
146 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
147 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR,
148 wide ? f->w : f->h);
149 input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR,
150 wide ? f->h : f->w);
134 input_mt_sync(input); 151 input_mt_sync(input);
135 /* 152 /*
136 * touchscreen emulation: maintain the age rank 153 * touchscreen emulation: maintain the age rank
@@ -197,6 +214,14 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
197 case HID_DG_CONFIDENCE: 214 case HID_DG_CONFIDENCE:
198 md->valid = value; 215 md->valid = value;
199 break; 216 break;
217 case HID_DG_WIDTH:
218 if (md->valid)
219 md->f[md->curid].w = value;
220 break;
221 case HID_DG_HEIGHT:
222 if (md->valid)
223 md->f[md->curid].h = value;
224 break;
200 case HID_DG_CONTACTID: 225 case HID_DG_CONTACTID:
201 if (md->valid) { 226 if (md->valid) {
202 md->curid = value; 227 md->curid = value;
@@ -255,6 +280,7 @@ static void mmm_remove(struct hid_device *hdev)
255 280
256static const struct hid_device_id mmm_devices[] = { 281static const struct hid_device_id mmm_devices[] = {
257 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, 282 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
283 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
258 { } 284 { }
259}; 285};
260MODULE_DEVICE_TABLE(hid, mmm_devices); 286MODULE_DEVICE_TABLE(hid, mmm_devices);
@@ -287,5 +313,4 @@ static void __exit mmm_exit(void)
287 313
288module_init(mmm_init); 314module_init(mmm_init);
289module_exit(mmm_exit); 315module_exit(mmm_exit);
290MODULE_LICENSE("GPL");
291 316
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 143e788b729b..69fdf1e2347b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -653,10 +653,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
653 if (device->driver->report_fixup) 653 if (device->driver->report_fixup)
654 device->driver->report_fixup(device, start, size); 654 device->driver->report_fixup(device, start, size);
655 655
656 device->rdesc = kmalloc(size, GFP_KERNEL); 656 device->rdesc = kmemdup(start, size, GFP_KERNEL);
657 if (device->rdesc == NULL) 657 if (device->rdesc == NULL)
658 return -ENOMEM; 658 return -ENOMEM;
659 memcpy(device->rdesc, start, size);
660 device->rsize = size; 659 device->rsize = size;
661 660
662 parser = vmalloc(sizeof(struct hid_parser)); 661 parser = vmalloc(sizeof(struct hid_parser));
@@ -940,13 +939,8 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
940 unsigned count = field->report_count; 939 unsigned count = field->report_count;
941 unsigned offset = field->report_offset; 940 unsigned offset = field->report_offset;
942 unsigned size = field->report_size; 941 unsigned size = field->report_size;
943 unsigned bitsused = offset + count * size;
944 unsigned n; 942 unsigned n;
945 943
946 /* make sure the unused bits in the last byte are zeros */
947 if (count > 0 && size > 0 && (bitsused % 8) != 0)
948 data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
949
950 for (n = 0; n < count; n++) { 944 for (n = 0; n < count; n++) {
951 if (field->logical_minimum < 0) /* signed values */ 945 if (field->logical_minimum < 0) /* signed values */
952 implement(data, offset + n * size, size, s32ton(field->value[n], size)); 946 implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@ -966,6 +960,7 @@ void hid_output_report(struct hid_report *report, __u8 *data)
966 if (report->id > 0) 960 if (report->id > 0)
967 *data++ = report->id; 961 *data++ = report->id;
968 962
963 memset(data, 0, ((report->size - 1) >> 3) + 1);
969 for (n = 0; n < report->maxfield; n++) 964 for (n = 0; n < report->maxfield; n++)
970 hid_output_field(report->field[n], data); 965 hid_output_field(report->field[n], data);
971} 966}
@@ -1167,6 +1162,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1167 unsigned int i; 1162 unsigned int i;
1168 int len; 1163 int len;
1169 1164
1165 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
1166 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
1170 if (hdev->bus != BUS_USB) 1167 if (hdev->bus != BUS_USB)
1171 connect_mask &= ~HID_CONNECT_HIDDEV; 1168 connect_mask &= ~HID_CONNECT_HIDDEV;
1172 if (hid_hiddev(hdev)) 1169 if (hid_hiddev(hdev))
@@ -1246,6 +1243,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
1246/* a list of devices for which there is a specialized driver on HID bus */ 1243/* a list of devices for which there is a specialized driver on HID bus */
1247static const struct hid_device_id hid_blacklist[] = { 1244static const struct hid_device_id hid_blacklist[] = {
1248 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, 1245 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
1246 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
1249 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1247 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
1250 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1248 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1251 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
@@ -1290,6 +1288,7 @@ static const struct hid_device_id hid_blacklist[] = {
1290 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1288 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1291 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1289 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1292 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, 1290 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
1291 { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
1293 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, 1292 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
1294 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, 1293 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
1295 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
@@ -1343,6 +1342,7 @@ static const struct hid_device_id hid_blacklist[] = {
1343 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1342 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1344 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1343 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1345 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1344 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1345 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1346 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1346 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1347 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1347 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1348 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1348 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
@@ -1359,8 +1359,10 @@ static const struct hid_device_id hid_blacklist[] = {
1359 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, 1359 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
1360 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1360 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1361 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1361 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1362 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
1362 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1363 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1363 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1364 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1365 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
1364 1366
1365 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1367 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1366 { } 1368 { }
@@ -1757,7 +1759,7 @@ int hid_add_device(struct hid_device *hdev)
1757 1759
1758 /* we need to kill them here, otherwise they will stay allocated to 1760 /* we need to kill them here, otherwise they will stay allocated to
1759 * wait for coming driver */ 1761 * wait for coming driver */
1760 if (hid_ignore(hdev)) 1762 if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
1761 return -ENODEV; 1763 return -ENODEV;
1762 1764
1763 /* XXX hack, any other cleaner solution after the driver core 1765 /* XXX hack, any other cleaner solution after the driver core
@@ -1765,11 +1767,12 @@ int hid_add_device(struct hid_device *hdev)
1765 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, 1767 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
1766 hdev->vendor, hdev->product, atomic_inc_return(&id)); 1768 hdev->vendor, hdev->product, atomic_inc_return(&id));
1767 1769
1770 hid_debug_register(hdev, dev_name(&hdev->dev));
1768 ret = device_add(&hdev->dev); 1771 ret = device_add(&hdev->dev);
1769 if (!ret) 1772 if (!ret)
1770 hdev->status |= HID_STAT_ADDED; 1773 hdev->status |= HID_STAT_ADDED;
1771 1774 else
1772 hid_debug_register(hdev, dev_name(&hdev->dev)); 1775 hid_debug_unregister(hdev);
1773 1776
1774 return ret; 1777 return ret;
1775} 1778}
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 09d27649a0f7..d55b81d2d16e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -20,6 +20,7 @@
20 20
21#define USB_VENDOR_ID_3M 0x0596 21#define USB_VENDOR_ID_3M 0x0596
22#define USB_DEVICE_ID_3M1968 0x0500 22#define USB_DEVICE_ID_3M1968 0x0500
23#define USB_DEVICE_ID_3M2256 0x0502
23 24
24#define USB_VENDOR_ID_A4TECH 0x09da 25#define USB_VENDOR_ID_A4TECH 0x09da
25#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 26#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
@@ -123,6 +124,9 @@
123#define USB_VENDOR_ID_BERKSHIRE 0x0c98 124#define USB_VENDOR_ID_BERKSHIRE 0x0c98
124#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 125#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
125 126
127#define USB_VENDOR_ID_BTC 0x046e
128#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
129
126#define USB_VENDOR_ID_CH 0x068e 130#define USB_VENDOR_ID_CH 0x068e
127#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 131#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
128#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4 132#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
@@ -171,6 +175,9 @@
171 175
172#define USB_VENDOR_ID_DRAGONRISE 0x0079 176#define USB_VENDOR_ID_DRAGONRISE 0x0079
173 177
178#define USB_VENDOR_ID_EGALAX 0x0EEF
179#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
180
174#define USB_VENDOR_ID_ELO 0x04E7 181#define USB_VENDOR_ID_ELO 0x04E7
175#define USB_DEVICE_ID_ELO_TS2700 0x0020 182#define USB_DEVICE_ID_ELO_TS2700 0x0020
176 183
@@ -409,6 +416,7 @@
409 416
410#define USB_VENDOR_ID_SAMSUNG 0x0419 417#define USB_VENDOR_ID_SAMSUNG 0x0419
411#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 418#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
419#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
412 420
413#define USB_VENDOR_ID_SONY 0x054c 421#define USB_VENDOR_ID_SONY 0x054c
414#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b 422#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
@@ -457,6 +465,7 @@
457 465
458#define USB_VENDOR_ID_WACOM 0x056a 466#define USB_VENDOR_ID_WACOM 0x056a
459#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 467#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
468#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0xbd
460 469
461#define USB_VENDOR_ID_WISEGROUP 0x0925 470#define USB_VENDOR_ID_WISEGROUP 0x0925
462#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 471#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
@@ -475,6 +484,9 @@
475 484
476#define USB_VENDOR_ID_ZEROPLUS 0x0c12 485#define USB_VENDOR_ID_ZEROPLUS 0x0c12
477 486
487#define USB_VENDOR_ID_ZYDACRON 0x13EC
488#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
489
478#define USB_VENDOR_ID_KYE 0x0458 490#define USB_VENDOR_ID_KYE 0x0458
479#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 491#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
480#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 492#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 3677c9037a11..f6433d8050a9 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -126,6 +126,9 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
126 case 0x1004: lg_map_key_clear(KEY_VIDEO); break; 126 case 0x1004: lg_map_key_clear(KEY_VIDEO); break;
127 case 0x1005: lg_map_key_clear(KEY_AUDIO); break; 127 case 0x1005: lg_map_key_clear(KEY_AUDIO); break;
128 case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break; 128 case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break;
129 /* The following two entries are Playlist 1 and 2 on the MX3200 */
130 case 0x100f: lg_map_key_clear(KEY_FN_1); break;
131 case 0x1010: lg_map_key_clear(KEY_FN_2); break;
129 case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break; 132 case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break;
130 case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break; 133 case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break;
131 case 0x1013: lg_map_key_clear(KEY_CAMERA); break; 134 case 0x1013: lg_map_key_clear(KEY_CAMERA); break;
@@ -137,6 +140,7 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
137 case 0x1019: lg_map_key_clear(KEY_PROG1); break; 140 case 0x1019: lg_map_key_clear(KEY_PROG1); break;
138 case 0x101a: lg_map_key_clear(KEY_PROG2); break; 141 case 0x101a: lg_map_key_clear(KEY_PROG2); break;
139 case 0x101b: lg_map_key_clear(KEY_PROG3); break; 142 case 0x101b: lg_map_key_clear(KEY_PROG3); break;
143 case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS); break;
140 case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break; 144 case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break;
141 case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break; 145 case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break;
142 case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break; 146 case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break;
@@ -147,6 +151,11 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
147 case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break; 151 case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break;
148 case 0x102a: lg_map_key_clear(KEY_BACK); break; 152 case 0x102a: lg_map_key_clear(KEY_BACK); break;
149 case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break; 153 case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break;
154 case 0x102d: lg_map_key_clear(KEY_WWW); break;
155 /* The following two are 'Start/answer call' and 'End/reject call'
156 on the MX3200 */
157 case 0x1031: lg_map_key_clear(KEY_OK); break;
158 case 0x1032: lg_map_key_clear(KEY_CANCEL); break;
150 case 0x1041: lg_map_key_clear(KEY_BATTERY); break; 159 case 0x1041: lg_map_key_clear(KEY_BATTERY); break;
151 case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break; 160 case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break;
152 case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break; 161 case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break;
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 510dd1340597..bda0fd60c98d 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -7,6 +7,18 @@
7 * Copyright (c) 2006-2007 Jiri Kosina 7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley 8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby 9 * Copyright (c) 2008 Jiri Slaby
10 * Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
11 *
12 *
13 * This driver supports several HID devices:
14 *
15 * [0419:0001] Samsung IrDA remote controller (reports as Cypress USB Mouse).
16 * various hid report fixups for different variants.
17 *
18 * [0419:0600] Creative Desktop Wireless 6000 keyboard/mouse combo
19 * several key mappings used from the consumer usage page
20 * deviate from the USB HUT 1.12 standard.
21 *
10 */ 22 */
11 23
12/* 24/*
@@ -17,14 +29,13 @@
17 */ 29 */
18 30
19#include <linux/device.h> 31#include <linux/device.h>
32#include <linux/usb.h>
20#include <linux/hid.h> 33#include <linux/hid.h>
21#include <linux/module.h> 34#include <linux/module.h>
22 35
23#include "hid-ids.h" 36#include "hid-ids.h"
24 37
25/* 38/*
26 * Samsung IrDA remote controller (reports as Cypress USB Mouse).
27 *
28 * There are several variants for 0419:0001: 39 * There are several variants for 0419:0001:
29 * 40 *
30 * 1. 184 byte report descriptor 41 * 1. 184 byte report descriptor
@@ -43,21 +54,21 @@
43 * 4. 171 byte report descriptor 54 * 4. 171 byte report descriptor
44 * Report #3 has an array field with logical range 0..1 instead of 1..3. 55 * Report #3 has an array field with logical range 0..1 instead of 1..3.
45 */ 56 */
46static inline void samsung_dev_trace(struct hid_device *hdev, 57static inline void samsung_irda_dev_trace(struct hid_device *hdev,
47 unsigned int rsize) 58 unsigned int rsize)
48{ 59{
49 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " 60 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
50 "descriptor\n", rsize); 61 "descriptor\n", rsize);
51} 62}
52 63
53static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, 64static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
54 unsigned int rsize) 65 unsigned int rsize)
55{ 66{
56 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && 67 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
57 rdesc[177] == 0x75 && rdesc[178] == 0x30 && 68 rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
58 rdesc[179] == 0x95 && rdesc[180] == 0x01 && 69 rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
59 rdesc[182] == 0x40) { 70 rdesc[182] == 0x40) {
60 samsung_dev_trace(hdev, 184); 71 samsung_irda_dev_trace(hdev, 184);
61 rdesc[176] = 0xff; 72 rdesc[176] = 0xff;
62 rdesc[178] = 0x08; 73 rdesc[178] = 0x08;
63 rdesc[180] = 0x06; 74 rdesc[180] = 0x06;
@@ -65,24 +76,80 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
65 } else 76 } else
66 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && 77 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
67 rdesc[194] == 0x25 && rdesc[195] == 0x12) { 78 rdesc[194] == 0x25 && rdesc[195] == 0x12) {
68 samsung_dev_trace(hdev, 203); 79 samsung_irda_dev_trace(hdev, 203);
69 rdesc[193] = 0x1; 80 rdesc[193] = 0x1;
70 rdesc[195] = 0xf; 81 rdesc[195] = 0xf;
71 } else 82 } else
72 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && 83 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
73 rdesc[126] == 0x25 && rdesc[127] == 0x11) { 84 rdesc[126] == 0x25 && rdesc[127] == 0x11) {
74 samsung_dev_trace(hdev, 135); 85 samsung_irda_dev_trace(hdev, 135);
75 rdesc[125] = 0x1; 86 rdesc[125] = 0x1;
76 rdesc[127] = 0xe; 87 rdesc[127] = 0xe;
77 } else 88 } else
78 if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && 89 if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
79 rdesc[162] == 0x25 && rdesc[163] == 0x01) { 90 rdesc[162] == 0x25 && rdesc[163] == 0x01) {
80 samsung_dev_trace(hdev, 171); 91 samsung_irda_dev_trace(hdev, 171);
81 rdesc[161] = 0x1; 92 rdesc[161] = 0x1;
82 rdesc[163] = 0x3; 93 rdesc[163] = 0x3;
83 } 94 }
84} 95}
85 96
97#define samsung_kbd_mouse_map_key_clear(c) \
98 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
99
100static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
101 struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
102 unsigned long **bit, int *max)
103{
104 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
105 unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
106
107 if (1 != ifnum || HID_UP_CONSUMER != (usage->hid & HID_USAGE_PAGE))
108 return 0;
109
110 dbg_hid("samsung wireless keyboard/mouse input mapping event [0x%x]\n",
111 usage->hid & HID_USAGE);
112
113 switch (usage->hid & HID_USAGE) {
114 /* report 2 */
115 case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
116 case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL); break;
117 case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
118 case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
119 case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
120 case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
121 case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
122 case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
123 case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
124 case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
125 case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
126 default:
127 return 0;
128 }
129
130 return 1;
131}
132
133static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
134 unsigned int rsize)
135{
136 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
137 samsung_irda_report_fixup(hdev, rdesc, rsize);
138}
139
140static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
141 struct hid_field *field, struct hid_usage *usage,
142 unsigned long **bit, int *max)
143{
144 int ret = 0;
145
146 if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
147 ret = samsung_kbd_mouse_input_mapping(hdev,
148 hi, field, usage, bit, max);
149
150 return ret;
151}
152
86static int samsung_probe(struct hid_device *hdev, 153static int samsung_probe(struct hid_device *hdev,
87 const struct hid_device_id *id) 154 const struct hid_device_id *id)
88{ 155{
@@ -95,10 +162,12 @@ static int samsung_probe(struct hid_device *hdev,
95 goto err_free; 162 goto err_free;
96 } 163 }
97 164
98 if (hdev->rsize == 184) { 165 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
99 /* disable hidinput, force hiddev */ 166 if (hdev->rsize == 184) {
100 cmask = (cmask & ~HID_CONNECT_HIDINPUT) | 167 /* disable hidinput, force hiddev */
101 HID_CONNECT_HIDDEV_FORCE; 168 cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
169 HID_CONNECT_HIDDEV_FORCE;
170 }
102 } 171 }
103 172
104 ret = hid_hw_start(hdev, cmask); 173 ret = hid_hw_start(hdev, cmask);
@@ -114,6 +183,7 @@ err_free:
114 183
115static const struct hid_device_id samsung_devices[] = { 184static const struct hid_device_id samsung_devices[] = {
116 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 185 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
186 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
117 { } 187 { }
118}; 188};
119MODULE_DEVICE_TABLE(hid, samsung_devices); 189MODULE_DEVICE_TABLE(hid, samsung_devices);
@@ -122,6 +192,7 @@ static struct hid_driver samsung_driver = {
122 .name = "samsung", 192 .name = "samsung",
123 .id_table = samsung_devices, 193 .id_table = samsung_devices,
124 .report_fixup = samsung_report_fixup, 194 .report_fixup = samsung_report_fixup,
195 .input_mapping = samsung_input_mapping,
125 .probe = samsung_probe, 196 .probe = samsung_probe,
126}; 197};
127 198
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 6925eda1081a..2eebdcc57bcf 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -3,6 +3,9 @@
3 * 3 *
4 * Copyright (c) 2008 Lev Babiev 4 * Copyright (c) 2008 Lev Babiev
5 * based on hid-cherry driver 5 * based on hid-cherry driver
6 *
7 * Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by
8 * Wayne Thomas 2010.
6 */ 9 */
7 10
8/* 11/*
@@ -24,23 +27,29 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
24 struct hid_field *field, struct hid_usage *usage, 27 struct hid_field *field, struct hid_usage *usage,
25 unsigned long **bit, int *max) 28 unsigned long **bit, int *max)
26{ 29{
27 if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000) 30 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
28 return 0; 31 return 0;
29 32
30 switch (usage->hid & HID_USAGE) { 33 switch (usage->hid & HID_USAGE) {
31 case 0x00d: ts_map_key_clear(KEY_HOME); break; 34 case 0x00d: ts_map_key_clear(KEY_MEDIA); break;
32 case 0x024: ts_map_key_clear(KEY_MENU); break; 35 case 0x024: ts_map_key_clear(KEY_MENU); break;
33 case 0x025: ts_map_key_clear(KEY_TV); break; 36 case 0x025: ts_map_key_clear(KEY_TV); break;
34 case 0x048: ts_map_key_clear(KEY_RED); break; 37 case 0x031: ts_map_key_clear(KEY_AUDIO); break;
35 case 0x047: ts_map_key_clear(KEY_GREEN); break; 38 case 0x032: ts_map_key_clear(KEY_TEXT); break;
36 case 0x049: ts_map_key_clear(KEY_YELLOW); break; 39 case 0x033: ts_map_key_clear(KEY_CHANNEL); break;
37 case 0x04a: ts_map_key_clear(KEY_BLUE); break; 40 case 0x047: ts_map_key_clear(KEY_MP3); break;
38 case 0x04b: ts_map_key_clear(KEY_ANGLE); break; 41 case 0x048: ts_map_key_clear(KEY_TV2); break;
39 case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break; 42 case 0x049: ts_map_key_clear(KEY_CAMERA); break;
40 case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break; 43 case 0x04a: ts_map_key_clear(KEY_VIDEO); break;
41 case 0x031: ts_map_key_clear(KEY_AUDIO); break; 44 case 0x04b: ts_map_key_clear(KEY_ANGLE); break;
42 case 0x032: ts_map_key_clear(KEY_TEXT); break; 45 case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break;
43 case 0x033: ts_map_key_clear(KEY_CHANNEL); break; 46 case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break;
47 case 0x050: ts_map_key_clear(KEY_RADIO); break;
48 case 0x05a: ts_map_key_clear(KEY_TEXT); break;
49 case 0x05b: ts_map_key_clear(KEY_RED); break;
50 case 0x05c: ts_map_key_clear(KEY_GREEN); break;
51 case 0x05d: ts_map_key_clear(KEY_YELLOW); break;
52 case 0x05e: ts_map_key_clear(KEY_BLUE); break;
44 default: 53 default:
45 return 0; 54 return 0;
46 } 55 }
@@ -50,6 +59,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
50 59
51static const struct hid_device_id ts_devices[] = { 60static const struct hid_device_id ts_devices[] = {
52 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 61 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
62 { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
53 { } 63 { }
54}; 64};
55MODULE_DEVICE_TABLE(hid, ts_devices); 65MODULE_DEVICE_TABLE(hid, ts_devices);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index f947d8337e21..1e051f1171e4 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -22,14 +22,159 @@
22#include <linux/hid.h> 22#include <linux/hid.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
26#include <linux/power_supply.h>
27#endif
25 28
26#include "hid-ids.h" 29#include "hid-ids.h"
27 30
28struct wacom_data { 31struct wacom_data {
29 __u16 tool; 32 __u16 tool;
30 unsigned char butstate; 33 unsigned char butstate;
34 unsigned char high_speed;
35#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
36 int battery_capacity;
37 struct power_supply battery;
38 struct power_supply ac;
39#endif
31}; 40};
32 41
42#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
43/*percent of battery capacity, 0 means AC online*/
44static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
45
46static enum power_supply_property wacom_battery_props[] = {
47 POWER_SUPPLY_PROP_PRESENT,
48 POWER_SUPPLY_PROP_CAPACITY
49};
50
51static enum power_supply_property wacom_ac_props[] = {
52 POWER_SUPPLY_PROP_PRESENT,
53 POWER_SUPPLY_PROP_ONLINE
54};
55
56static int wacom_battery_get_property(struct power_supply *psy,
57 enum power_supply_property psp,
58 union power_supply_propval *val)
59{
60 struct wacom_data *wdata = container_of(psy,
61 struct wacom_data, battery);
62 int power_state = batcap[wdata->battery_capacity];
63 int ret = 0;
64
65 switch (psp) {
66 case POWER_SUPPLY_PROP_PRESENT:
67 val->intval = 1;
68 break;
69 case POWER_SUPPLY_PROP_CAPACITY:
70 /* show 100% battery capacity when charging */
71 if (power_state == 0)
72 val->intval = 100;
73 else
74 val->intval = power_state;
75 break;
76 default:
77 ret = -EINVAL;
78 break;
79 }
80 return ret;
81}
82
83static int wacom_ac_get_property(struct power_supply *psy,
84 enum power_supply_property psp,
85 union power_supply_propval *val)
86{
87 struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
88 int power_state = batcap[wdata->battery_capacity];
89 int ret = 0;
90
91 switch (psp) {
92 case POWER_SUPPLY_PROP_PRESENT:
93 /* fall through */
94 case POWER_SUPPLY_PROP_ONLINE:
95 if (power_state == 0)
96 val->intval = 1;
97 else
98 val->intval = 0;
99 break;
100 default:
101 ret = -EINVAL;
102 break;
103 }
104 return ret;
105}
106#endif
107
108static void wacom_poke(struct hid_device *hdev, u8 speed)
109{
110 struct wacom_data *wdata = hid_get_drvdata(hdev);
111 int limit, ret;
112 char rep_data[2];
113
114 rep_data[0] = 0x03 ; rep_data[1] = 0x00;
115 limit = 3;
116 do {
117 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
118 HID_FEATURE_REPORT);
119 } while (ret < 0 && limit-- > 0);
120
121 if (ret >= 0) {
122 if (speed == 0)
123 rep_data[0] = 0x05;
124 else
125 rep_data[0] = 0x06;
126
127 rep_data[1] = 0x00;
128 limit = 3;
129 do {
130 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
131 HID_FEATURE_REPORT);
132 } while (ret < 0 && limit-- > 0);
133
134 if (ret >= 0) {
135 wdata->high_speed = speed;
136 return;
137 }
138 }
139
140 /*
141 * Note that if the raw queries fail, it's not a hard failure and it
142 * is safe to continue
143 */
144 dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n",
145 rep_data[0], ret);
146 return;
147}
148
149static ssize_t wacom_show_speed(struct device *dev,
150 struct device_attribute
151 *attr, char *buf)
152{
153 struct wacom_data *wdata = dev_get_drvdata(dev);
154
155 return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
156}
157
158static ssize_t wacom_store_speed(struct device *dev,
159 struct device_attribute *attr,
160 const char *buf, size_t count)
161{
162 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
163 int new_speed;
164
165 if (sscanf(buf, "%1d", &new_speed ) != 1)
166 return -EINVAL;
167
168 if (new_speed == 0 || new_speed == 1) {
169 wacom_poke(hdev, new_speed);
170 return strnlen(buf, PAGE_SIZE);
171 } else
172 return -EINVAL;
173}
174
175static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO,
176 wacom_show_speed, wacom_store_speed);
177
33static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, 178static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
34 u8 *raw_data, int size) 179 u8 *raw_data, int size)
35{ 180{
@@ -148,6 +293,12 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
148 input_sync(input); 293 input_sync(input);
149 } 294 }
150 295
296#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
297 /* Store current battery capacity */
298 rw = (data[7] >> 2 & 0x07);
299 if (rw != wdata->battery_capacity)
300 wdata->battery_capacity = rw;
301#endif
151 return 1; 302 return 1;
152} 303}
153 304
@@ -157,9 +308,7 @@ static int wacom_probe(struct hid_device *hdev,
157 struct hid_input *hidinput; 308 struct hid_input *hidinput;
158 struct input_dev *input; 309 struct input_dev *input;
159 struct wacom_data *wdata; 310 struct wacom_data *wdata;
160 char rep_data[2];
161 int ret; 311 int ret;
162 int limit;
163 312
164 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); 313 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
165 if (wdata == NULL) { 314 if (wdata == NULL) {
@@ -182,31 +331,53 @@ static int wacom_probe(struct hid_device *hdev,
182 goto err_free; 331 goto err_free;
183 } 332 }
184 333
185 /* 334 ret = device_create_file(&hdev->dev, &dev_attr_speed);
186 * Note that if the raw queries fail, it's not a hard failure and it 335 if (ret)
187 * is safe to continue 336 dev_warn(&hdev->dev,
188 */ 337 "can't create sysfs speed attribute err: %d\n", ret);
189 338
190 /* Set Wacom mode2 */ 339 /* Set Wacom mode 2 with high reporting speed */
191 rep_data[0] = 0x03; rep_data[1] = 0x00; 340 wacom_poke(hdev, 1);
192 limit = 3;
193 do {
194 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
195 HID_FEATURE_REPORT);
196 } while (ret < 0 && limit-- > 0);
197 if (ret < 0)
198 dev_warn(&hdev->dev, "failed to poke device #1, %d\n", ret);
199 341
200 /* 0x06 - high reporting speed, 0x05 - low speed */ 342#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
201 rep_data[0] = 0x06; rep_data[1] = 0x00; 343 wdata->battery.properties = wacom_battery_props;
202 limit = 3; 344 wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
203 do { 345 wdata->battery.get_property = wacom_battery_get_property;
204 ret = hdev->hid_output_raw_report(hdev, rep_data, 2, 346 wdata->battery.name = "wacom_battery";
205 HID_FEATURE_REPORT); 347 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
206 } while (ret < 0 && limit-- > 0); 348 wdata->battery.use_for_apm = 0;
207 if (ret < 0)
208 dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);
209 349
350 ret = power_supply_register(&hdev->dev, &wdata->battery);
351 if (ret) {
352 dev_warn(&hdev->dev,
353 "can't create sysfs battery attribute, err: %d\n", ret);
354 /*
355 * battery attribute is not critical for the tablet, but if it
356 * failed then there is no need to create ac attribute
357 */
358 goto move_on;
359 }
360
361 wdata->ac.properties = wacom_ac_props;
362 wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
363 wdata->ac.get_property = wacom_ac_get_property;
364 wdata->ac.name = "wacom_ac";
365 wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
366 wdata->ac.use_for_apm = 0;
367
368 ret = power_supply_register(&hdev->dev, &wdata->ac);
369 if (ret) {
370 dev_warn(&hdev->dev,
371 "can't create ac battery attribute, err: %d\n", ret);
372 /*
373 * ac attribute is not critical for the tablet, but if it
374 * failed then we don't want to battery attribute to exist
375 */
376 power_supply_unregister(&wdata->battery);
377 }
378
379move_on:
380#endif
210 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 381 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
211 input = hidinput->input; 382 input = hidinput->input;
212 383
@@ -251,13 +422,21 @@ err_free:
251 422
252static void wacom_remove(struct hid_device *hdev) 423static void wacom_remove(struct hid_device *hdev)
253{ 424{
425#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
426 struct wacom_data *wdata = hid_get_drvdata(hdev);
427#endif
254 hid_hw_stop(hdev); 428 hid_hw_stop(hdev);
429
430#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
431 power_supply_unregister(&wdata->battery);
432 power_supply_unregister(&wdata->ac);
433#endif
255 kfree(hid_get_drvdata(hdev)); 434 kfree(hid_get_drvdata(hdev));
256} 435}
257 436
258static const struct hid_device_id wacom_devices[] = { 437static const struct hid_device_id wacom_devices[] = {
259 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 438 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
260 439 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
261 { } 440 { }
262}; 441};
263MODULE_DEVICE_TABLE(hid, wacom_devices); 442MODULE_DEVICE_TABLE(hid, wacom_devices);
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
new file mode 100644
index 000000000000..9e8d35a203e4
--- /dev/null
+++ b/drivers/hid/hid-zydacron.c
@@ -0,0 +1,237 @@
1/*
2* HID driver for zydacron remote control
3*
4* Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
5*/
6
7/*
8* This program is free software; you can redistribute it and/or modify it
9* under the terms of the GNU General Public License as published by the Free
10* Software Foundation; either version 2 of the License, or (at your option)
11* any later version.
12*/
13
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/module.h>
17
18#include "hid-ids.h"
19
20struct zc_device {
21 struct input_dev *input_ep81;
22 unsigned short last_key[4];
23};
24
25
26/*
27* Zydacron remote control has an invalid HID report descriptor,
28* that needs fixing before we can parse it.
29*/
30static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
31 unsigned int rsize)
32{
33 if (rsize >= 253 &&
34 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
35 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
36 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
37 dev_info(&hdev->dev,
38 "fixing up zydacron remote control report "
39 "descriptor\n");
40 rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
41 rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
42 }
43}
44
45#define zc_map_key_clear(c) \
46 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
47
48static int zc_input_mapping(struct hid_device *hdev, struct hid_input *hi,
49 struct hid_field *field, struct hid_usage *usage,
50 unsigned long **bit, int *max)
51{
52 int i;
53 struct zc_device *zc = hid_get_drvdata(hdev);
54 zc->input_ep81 = hi->input;
55
56 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
57 return 0;
58
59 dbg_hid("zynacron input mapping event [0x%x]\n",
60 usage->hid & HID_USAGE);
61
62 switch (usage->hid & HID_USAGE) {
63 /* report 2 */
64 case 0x10:
65 zc_map_key_clear(KEY_MODE);
66 break;
67 case 0x30:
68 zc_map_key_clear(KEY_SCREEN);
69 break;
70 case 0x70:
71 zc_map_key_clear(KEY_INFO);
72 break;
73 /* report 3 */
74 case 0x04:
75 zc_map_key_clear(KEY_RADIO);
76 break;
77 /* report 4 */
78 case 0x0d:
79 zc_map_key_clear(KEY_PVR);
80 break;
81 case 0x25:
82 zc_map_key_clear(KEY_TV);
83 break;
84 case 0x47:
85 zc_map_key_clear(KEY_AUDIO);
86 break;
87 case 0x49:
88 zc_map_key_clear(KEY_AUX);
89 break;
90 case 0x4a:
91 zc_map_key_clear(KEY_VIDEO);
92 break;
93 case 0x48:
94 zc_map_key_clear(KEY_DVD);
95 break;
96 case 0x24:
97 zc_map_key_clear(KEY_MENU);
98 break;
99 case 0x32:
100 zc_map_key_clear(KEY_TEXT);
101 break;
102 default:
103 return 0;
104 }
105
106 for (i = 0; i < 4; i++)
107 zc->last_key[i] = 0;
108
109 return 1;
110}
111
112static int zc_raw_event(struct hid_device *hdev, struct hid_report *report,
113 u8 *data, int size)
114{
115 struct zc_device *zc = hid_get_drvdata(hdev);
116 int ret = 0;
117 unsigned key;
118 unsigned short index;
119
120 if (report->id == data[0]) {
121
122 /* break keys */
123 for (index = 0; index < 4; index++) {
124 key = zc->last_key[index];
125 if (key) {
126 input_event(zc->input_ep81, EV_KEY, key, 0);
127 zc->last_key[index] = 0;
128 }
129 }
130
131 key = 0;
132 switch (report->id) {
133 case 0x02:
134 case 0x03:
135 switch (data[1]) {
136 case 0x10:
137 key = KEY_MODE;
138 index = 0;
139 break;
140 case 0x30:
141 key = KEY_SCREEN;
142 index = 1;
143 break;
144 case 0x70:
145 key = KEY_INFO;
146 index = 2;
147 break;
148 case 0x04:
149 key = KEY_RADIO;
150 index = 3;
151 break;
152 }
153
154 if (key) {
155 input_event(zc->input_ep81, EV_KEY, key, 1);
156 zc->last_key[index] = key;
157 }
158
159 ret = 1;
160 break;
161 }
162 }
163
164 return ret;
165}
166
167static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id)
168{
169 int ret;
170 struct zc_device *zc;
171
172 zc = kzalloc(sizeof(*zc), GFP_KERNEL);
173 if (zc == NULL) {
174 dev_err(&hdev->dev, "zydacron: can't alloc descriptor\n");
175 return -ENOMEM;
176 }
177
178 hid_set_drvdata(hdev, zc);
179
180 ret = hid_parse(hdev);
181 if (ret) {
182 dev_err(&hdev->dev, "zydacron: parse failed\n");
183 goto err_free;
184 }
185
186 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
187 if (ret) {
188 dev_err(&hdev->dev, "zydacron: hw start failed\n");
189 goto err_free;
190 }
191
192 return 0;
193err_free:
194 kfree(zc);
195
196 return ret;
197}
198
199static void zc_remove(struct hid_device *hdev)
200{
201 struct zc_device *zc = hid_get_drvdata(hdev);
202
203 hid_hw_stop(hdev);
204
205 if (NULL != zc)
206 kfree(zc);
207}
208
209static const struct hid_device_id zc_devices[] = {
210 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
211 { }
212};
213MODULE_DEVICE_TABLE(hid, zc_devices);
214
215static struct hid_driver zc_driver = {
216 .name = "zydacron",
217 .id_table = zc_devices,
218 .report_fixup = zc_report_fixup,
219 .input_mapping = zc_input_mapping,
220 .raw_event = zc_raw_event,
221 .probe = zc_probe,
222 .remove = zc_remove,
223};
224
225static int __init zc_init(void)
226{
227 return hid_register_driver(&zc_driver);
228}
229
230static void __exit zc_exit(void)
231{
232 hid_unregister_driver(&zc_driver);
233}
234
235module_init(zc_init);
236module_exit(zc_exit);
237MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 6eadf1a9b3cc..a9becf9cd0f6 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -311,7 +311,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
311 -EFAULT : len; 311 -EFAULT : len;
312 break; 312 break;
313 } 313 }
314 } 314 }
315 315
316 ret = -ENOTTY; 316 ret = -ENOTTY;
317 } 317 }
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7b85b696fdab..a2ebe1996740 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -807,16 +807,36 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
807 struct usb_host_interface *interface = intf->cur_altsetting; 807 struct usb_host_interface *interface = intf->cur_altsetting;
808 int ret; 808 int ret;
809 809
810 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 810 if (usbhid->urbout) {
811 HID_REQ_SET_REPORT, 811 int actual_length;
812 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 812 int skipped_report_id = 0;
813 ((report_type + 1) << 8) | *buf, 813 if (buf[0] == 0x0) {
814 interface->desc.bInterfaceNumber, buf + 1, count - 1, 814 /* Don't send the Report ID */
815 USB_CTRL_SET_TIMEOUT); 815 buf++;
816 816 count--;
817 /* count also the report id */ 817 skipped_report_id = 1;
818 if (ret > 0) 818 }
819 ret++; 819 ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
820 buf, count, &actual_length,
821 USB_CTRL_SET_TIMEOUT);
822 /* return the number of bytes transferred */
823 if (ret == 0) {
824 ret = actual_length;
825 /* count also the report id */
826 if (skipped_report_id)
827 ret++;
828 }
829 } else {
830 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
831 HID_REQ_SET_REPORT,
832 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
833 ((report_type + 1) << 8) | *buf,
834 interface->desc.bInterfaceNumber, buf + 1, count - 1,
835 USB_CTRL_SET_TIMEOUT);
836 /* count also the report id */
837 if (ret > 0)
838 ret++;
839 }
820 840
821 return ret; 841 return ret;
822} 842}
@@ -1019,12 +1039,15 @@ static int usbhid_start(struct hid_device *hid)
1019 /* Some keyboards don't work until their LEDs have been set. 1039 /* Some keyboards don't work until their LEDs have been set.
1020 * Since BIOSes do set the LEDs, it must be safe for any device 1040 * Since BIOSes do set the LEDs, it must be safe for any device
1021 * that supports the keyboard boot protocol. 1041 * that supports the keyboard boot protocol.
1042 * In addition, enable remote wakeup by default for all keyboard
1043 * devices supporting the boot protocol.
1022 */ 1044 */
1023 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT && 1045 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
1024 interface->desc.bInterfaceProtocol == 1046 interface->desc.bInterfaceProtocol ==
1025 USB_INTERFACE_PROTOCOL_KEYBOARD) 1047 USB_INTERFACE_PROTOCOL_KEYBOARD) {
1026 usbhid_set_leds(hid); 1048 usbhid_set_leds(hid);
1027 1049 device_set_wakeup_enable(&dev->dev, 1);
1050 }
1028 return 0; 1051 return 0;
1029 1052
1030fail: 1053fail:
@@ -1133,6 +1156,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1133 hid->vendor = le16_to_cpu(dev->descriptor.idVendor); 1156 hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
1134 hid->product = le16_to_cpu(dev->descriptor.idProduct); 1157 hid->product = le16_to_cpu(dev->descriptor.idProduct);
1135 hid->name[0] = 0; 1158 hid->name[0] = 0;
1159 hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);
1136 if (intf->cur_altsetting->desc.bInterfaceProtocol == 1160 if (intf->cur_altsetting->desc.bInterfaceProtocol ==
1137 USB_INTERFACE_PROTOCOL_MOUSE) 1161 USB_INTERFACE_PROTOCOL_MOUSE)
1138 hid->type = HID_TYPE_USBMOUSE; 1162 hid->type = HID_TYPE_USBMOUSE;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 1152f9b5fd44..7a6bda23283e 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -33,6 +33,7 @@ static const struct hid_blacklist {
33 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, 33 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
34 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, 34 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
35 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, 35 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
36 { USB_VENDOR_ID_EGALAX, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT },
36 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 37 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
37 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 38 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
38 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 39 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index f843443ba5c3..b2fd0b00de92 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -313,6 +313,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
313 goto fail2; 313 goto fail2;
314 314
315 usb_set_intfdata(iface, kbd); 315 usb_set_intfdata(iface, kbd);
316 device_set_wakeup_enable(&dev->dev, 1);
316 return 0; 317 return 0;
317 318
318fail2: 319fail2:
diff --git a/include/linux/hid.h b/include/linux/hid.h
index b1344ec4b7fc..f1f2b6f0d1c4 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -308,11 +308,13 @@ struct hid_item {
308#define HID_QUIRK_NOTOUCH 0x00000002 308#define HID_QUIRK_NOTOUCH 0x00000002
309#define HID_QUIRK_IGNORE 0x00000004 309#define HID_QUIRK_IGNORE 0x00000004
310#define HID_QUIRK_NOGET 0x00000008 310#define HID_QUIRK_NOGET 0x00000008
311#define HID_QUIRK_HIDDEV_FORCE 0x00000010
311#define HID_QUIRK_BADPAD 0x00000020 312#define HID_QUIRK_BADPAD 0x00000020
312#define HID_QUIRK_MULTI_INPUT 0x00000040 313#define HID_QUIRK_MULTI_INPUT 0x00000040
313#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 314#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
314#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 315#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
315#define HID_QUIRK_NO_INIT_REPORTS 0x20000000 316#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
317#define HID_QUIRK_NO_IGNORE 0x40000000
316 318
317/* 319/*
318 * This is the global environment of the parser. This information is 320 * This is the global environment of the parser. This information is