diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 16 | ||||
-rw-r--r-- | drivers/hid/hid-hyperv.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 19 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 18 | ||||
-rw-r--r-- | drivers/hid/hid-multitouch.c | 217 | ||||
-rw-r--r-- | drivers/hid/hid-prodikeys.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-wacom.c | 17 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-core.c | 10 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 4 |
11 files changed, 242 insertions, 66 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abdd1ab7..bfac1f79757f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -354,7 +354,9 @@ config HID_MULTITOUCH | |||
354 | - LG Display panels (Dell ST2220Tc) | 354 | - LG Display panels (Dell ST2220Tc) |
355 | - Lumio CrystalTouch panels | 355 | - Lumio CrystalTouch panels |
356 | - MosArt dual-touch panels | 356 | - MosArt dual-touch panels |
357 | - Panasonic multitouch panels | ||
357 | - PenMount dual touch panels | 358 | - PenMount dual touch panels |
359 | - Perixx Peripad 701 touchpad | ||
358 | - PixArt optical touch screen | 360 | - PixArt optical touch screen |
359 | - Pixcir dual touch panels | 361 | - Pixcir dual touch panels |
360 | - Quanta panels | 362 | - Quanta panels |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7207d9..05a0c9a35bf2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1232,7 +1232,6 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
1232 | hdev->claimed |= HID_CLAIMED_INPUT; | 1232 | hdev->claimed |= HID_CLAIMED_INPUT; |
1233 | if (hdev->quirks & HID_QUIRK_MULTITOUCH) { | 1233 | if (hdev->quirks & HID_QUIRK_MULTITOUCH) { |
1234 | /* this device should be handled by hid-multitouch, skip it */ | 1234 | /* this device should be handled by hid-multitouch, skip it */ |
1235 | hdev->quirks &= ~HID_QUIRK_MULTITOUCH; | ||
1236 | return -ENODEV; | 1235 | return -ENODEV; |
1237 | } | 1236 | } |
1238 | 1237 | ||
@@ -1409,6 +1408,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1409 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, | 1408 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, |
1410 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, | 1409 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, |
1411 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | 1410 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, |
1411 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | ||
1412 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | ||
1412 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | 1413 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, |
1413 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | 1414 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, |
1414 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, | 1415 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, |
@@ -1501,6 +1502,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1501 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, | 1502 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, |
1502 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, | 1503 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, |
1503 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1504 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1505 | { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) }, | ||
1506 | { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) }, | ||
1504 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, | 1507 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, |
1505 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1508 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1506 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, | 1509 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, |
@@ -1663,6 +1666,10 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) | |||
1663 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1666 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1664 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1667 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1665 | 1668 | ||
1669 | if ((hdev->quirks & HID_QUIRK_MULTITOUCH) && | ||
1670 | !strncmp(hdrv->name, "hid-multitouch", 14)) | ||
1671 | return 1; | ||
1672 | |||
1666 | if (!hid_match_device(hdev, hdrv)) | 1673 | if (!hid_match_device(hdev, hdrv)) |
1667 | return 0; | 1674 | return 0; |
1668 | 1675 | ||
@@ -1687,8 +1694,11 @@ static int hid_device_probe(struct device *dev) | |||
1687 | if (!hdev->driver) { | 1694 | if (!hdev->driver) { |
1688 | id = hid_match_device(hdev, hdrv); | 1695 | id = hid_match_device(hdev, hdrv); |
1689 | if (id == NULL) { | 1696 | if (id == NULL) { |
1690 | ret = -ENODEV; | 1697 | if (!((hdev->quirks & HID_QUIRK_MULTITOUCH) && |
1691 | goto unlock; | 1698 | !strncmp(hdrv->name, "hid-multitouch", 14))) { |
1699 | ret = -ENODEV; | ||
1700 | goto unlock; | ||
1701 | } | ||
1692 | } | 1702 | } |
1693 | 1703 | ||
1694 | hdev->driver = hdrv; | 1704 | hdev->driver = hdrv; |
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 0c33ae9cf0f0..406632472c1b 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
@@ -548,6 +548,7 @@ static int mousevsc_remove(struct hv_device *dev) | |||
548 | struct mousevsc_dev *input_dev = hv_get_drvdata(dev); | 548 | struct mousevsc_dev *input_dev = hv_get_drvdata(dev); |
549 | 549 | ||
550 | vmbus_close(dev->channel); | 550 | vmbus_close(dev->channel); |
551 | hid_hw_stop(input_dev->hid_device); | ||
551 | hid_destroy_device(input_dev->hid_device); | 552 | hid_destroy_device(input_dev->hid_device); |
552 | mousevsc_free_device(input_dev); | 553 | mousevsc_free_device(input_dev); |
553 | 554 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cddd953..55360fefee5b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #define USB_VENDOR_ID_ACTIONSTAR 0x2101 | 41 | #define USB_VENDOR_ID_ACTIONSTAR 0x2101 |
42 | #define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 | 42 | #define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 |
43 | 43 | ||
44 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | 44 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 |
45 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | 45 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 |
46 | 46 | ||
47 | #define USB_VENDOR_ID_AFATECH 0x15a4 | 47 | #define USB_VENDOR_ID_AFATECH 0x15a4 |
@@ -59,6 +59,9 @@ | |||
59 | #define USB_VENDOR_ID_AIRCABLE 0x16CA | 59 | #define USB_VENDOR_ID_AIRCABLE 0x16CA |
60 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 | 60 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 |
61 | 61 | ||
62 | #define USB_VENDOR_ID_AIREN 0x1a2c | ||
63 | #define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 | ||
64 | |||
62 | #define USB_VENDOR_ID_ALCOR 0x058f | 65 | #define USB_VENDOR_ID_ALCOR 0x058f |
63 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 | 66 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 |
64 | 67 | ||
@@ -149,6 +152,7 @@ | |||
149 | 152 | ||
150 | #define USB_VENDOR_ID_ATMEL 0x03eb | 153 | #define USB_VENDOR_ID_ATMEL 0x03eb |
151 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c | 154 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c |
155 | #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 | ||
152 | 156 | ||
153 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca | 157 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca |
154 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 | 158 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 |
@@ -237,11 +241,18 @@ | |||
237 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 241 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
238 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d | 242 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d |
239 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e | 243 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e |
244 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 | ||
240 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c | 245 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c |
246 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 | ||
247 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A 0x722A | ||
248 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e | ||
249 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 | ||
241 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b | 250 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b |
251 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa | ||
242 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 | 252 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 |
243 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa | 253 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa |
244 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 | 254 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 |
255 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 | ||
245 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 | 256 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 |
246 | 257 | ||
247 | #define USB_VENDOR_ID_ELECOM 0x056e | 258 | #define USB_VENDOR_ID_ELECOM 0x056e |
@@ -374,6 +385,7 @@ | |||
374 | 385 | ||
375 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 | 386 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 |
376 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 | 387 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 |
388 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 | ||
377 | 389 | ||
378 | #define USB_VENDOR_ID_ILITEK 0x222a | 390 | #define USB_VENDOR_ID_ILITEK 0x222a |
379 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 | 391 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 |
@@ -565,6 +577,10 @@ | |||
565 | #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 | 577 | #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 |
566 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 | 578 | #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 |
567 | 579 | ||
580 | #define USB_VENDOR_ID_PANASONIC 0x04da | ||
581 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 | ||
582 | #define USB_DEVICE_ID_PANABOARD_UBT880 0x104d | ||
583 | |||
568 | #define USB_VENDOR_ID_PANJIT 0x134c | 584 | #define USB_VENDOR_ID_PANJIT 0x134c |
569 | 585 | ||
570 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | 586 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 |
@@ -659,6 +675,7 @@ | |||
659 | 675 | ||
660 | #define USB_VENDOR_ID_TOPSEED2 0x1784 | 676 | #define USB_VENDOR_ID_TOPSEED2 0x1784 |
661 | #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 | 677 | #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 |
678 | #define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016 | ||
662 | 679 | ||
663 | #define USB_VENDOR_ID_TOPMAX 0x0663 | 680 | #define USB_VENDOR_ID_TOPMAX 0x0663 |
664 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 | 681 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9333d692a786..002781c5a616 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -279,7 +279,8 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
279 | POWER_SUPPLY_PROP_ONLINE, | 279 | POWER_SUPPLY_PROP_ONLINE, |
280 | POWER_SUPPLY_PROP_CAPACITY, | 280 | POWER_SUPPLY_PROP_CAPACITY, |
281 | POWER_SUPPLY_PROP_MODEL_NAME, | 281 | POWER_SUPPLY_PROP_MODEL_NAME, |
282 | POWER_SUPPLY_PROP_STATUS | 282 | POWER_SUPPLY_PROP_STATUS, |
283 | POWER_SUPPLY_PROP_SCOPE, | ||
283 | }; | 284 | }; |
284 | 285 | ||
285 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ | 286 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ |
@@ -344,6 +345,10 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
344 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 345 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
345 | break; | 346 | break; |
346 | 347 | ||
348 | case POWER_SUPPLY_PROP_SCOPE: | ||
349 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
350 | break; | ||
351 | |||
347 | default: | 352 | default: |
348 | ret = -EINVAL; | 353 | ret = -EINVAL; |
349 | break; | 354 | break; |
@@ -403,6 +408,8 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | |||
403 | battery->name = NULL; | 408 | battery->name = NULL; |
404 | } | 409 | } |
405 | 410 | ||
411 | power_supply_powers(battery, &dev->dev); | ||
412 | |||
406 | out: | 413 | out: |
407 | return true; | 414 | return true; |
408 | } | 415 | } |
@@ -986,8 +993,13 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
986 | return; | 993 | return; |
987 | } | 994 | } |
988 | 995 | ||
989 | /* Ignore out-of-range values as per HID specification, section 5.10 */ | 996 | /* |
990 | if (value < field->logical_minimum || value > field->logical_maximum) { | 997 | * Ignore out-of-range values as per HID specification, |
998 | * section 5.10 and 6.2.25 | ||
999 | */ | ||
1000 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && | ||
1001 | (value < field->logical_minimum || | ||
1002 | value > field->logical_maximum)) { | ||
991 | dbg_hid("Ignoring out-of-range value %x\n", value); | 1003 | dbg_hid("Ignoring out-of-range value %x\n", value); |
992 | return; | 1004 | return; |
993 | } | 1005 | } |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 24fc4423b937..6fb46d70f39d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * HID driver for multitouch panels | 2 | * HID driver for multitouch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> |
5 | * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> | 5 | * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> |
6 | * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France | 6 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France |
7 | * | 7 | * |
8 | * This code is partly based on hid-egalax.c: | 8 | * This code is partly based on hid-egalax.c: |
9 | * | 9 | * |
@@ -67,6 +67,7 @@ struct mt_class { | |||
67 | __s32 sn_height; /* Signal/noise ratio for height events */ | 67 | __s32 sn_height; /* Signal/noise ratio for height events */ |
68 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ | 68 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ |
69 | __u8 maxcontacts; | 69 | __u8 maxcontacts; |
70 | bool is_indirect; /* true for touchpads */ | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | struct mt_device { | 73 | struct mt_device { |
@@ -74,11 +75,15 @@ struct mt_device { | |||
74 | struct mt_class mtclass; /* our mt device class */ | 75 | struct mt_class mtclass; /* our mt device class */ |
75 | unsigned last_field_index; /* last field index of the report */ | 76 | unsigned last_field_index; /* last field index of the report */ |
76 | unsigned last_slot_field; /* the last field of a slot */ | 77 | unsigned last_slot_field; /* the last field of a slot */ |
77 | int last_mt_collection; /* last known mt-related collection */ | ||
78 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 78 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
79 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | ||
80 | -1 if non-existent */ | ||
79 | __u8 num_received; /* how many contacts we received */ | 81 | __u8 num_received; /* how many contacts we received */ |
80 | __u8 num_expected; /* expected last contact index */ | 82 | __u8 num_expected; /* expected last contact index */ |
81 | __u8 maxcontacts; | 83 | __u8 maxcontacts; |
84 | __u8 touches_by_report; /* how many touches are present in one report: | ||
85 | * 1 means we should use a serial protocol | ||
86 | * > 1 means hybrid (multitouch) protocol */ | ||
82 | bool curvalid; /* is the current contact valid? */ | 87 | bool curvalid; /* is the current contact valid? */ |
83 | struct mt_slot *slots; | 88 | struct mt_slot *slots; |
84 | }; | 89 | }; |
@@ -100,6 +105,8 @@ struct mt_device { | |||
100 | #define MT_CLS_CYPRESS 0x0102 | 105 | #define MT_CLS_CYPRESS 0x0102 |
101 | #define MT_CLS_EGALAX 0x0103 | 106 | #define MT_CLS_EGALAX 0x0103 |
102 | #define MT_CLS_EGALAX_SERIAL 0x0104 | 107 | #define MT_CLS_EGALAX_SERIAL 0x0104 |
108 | #define MT_CLS_TOPSEED 0x0105 | ||
109 | #define MT_CLS_PANASONIC 0x0106 | ||
103 | 110 | ||
104 | #define MT_DEFAULT_MAXCONTACT 10 | 111 | #define MT_DEFAULT_MAXCONTACT 10 |
105 | 112 | ||
@@ -189,6 +196,14 @@ static struct mt_class mt_classes[] = { | |||
189 | .sn_move = 4096, | 196 | .sn_move = 4096, |
190 | .sn_pressure = 32, | 197 | .sn_pressure = 32, |
191 | }, | 198 | }, |
199 | { .name = MT_CLS_TOPSEED, | ||
200 | .quirks = MT_QUIRK_ALWAYS_VALID, | ||
201 | .is_indirect = true, | ||
202 | .maxcontacts = 2, | ||
203 | }, | ||
204 | { .name = MT_CLS_PANASONIC, | ||
205 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, | ||
206 | .maxcontacts = 4 }, | ||
192 | 207 | ||
193 | { } | 208 | { } |
194 | }; | 209 | }; |
@@ -241,6 +256,7 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
241 | td->inputmode = field->report->id; | 256 | td->inputmode = field->report->id; |
242 | break; | 257 | break; |
243 | case HID_DG_CONTACTMAX: | 258 | case HID_DG_CONTACTMAX: |
259 | td->maxcontact_report_id = field->report->id; | ||
244 | td->maxcontacts = field->value[0]; | 260 | td->maxcontacts = field->value[0]; |
245 | if (td->mtclass.maxcontacts) | 261 | if (td->mtclass.maxcontacts) |
246 | /* check if the maxcontacts is given by the class */ | 262 | /* check if the maxcontacts is given by the class */ |
@@ -259,23 +275,44 @@ static void set_abs(struct input_dev *input, unsigned int code, | |||
259 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | 275 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); |
260 | } | 276 | } |
261 | 277 | ||
278 | static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td, | ||
279 | struct hid_input *hi) | ||
280 | { | ||
281 | if (!test_bit(usage->hid, hi->input->absbit)) | ||
282 | td->last_slot_field = usage->hid; | ||
283 | } | ||
284 | |||
262 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 285 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
263 | struct hid_field *field, struct hid_usage *usage, | 286 | struct hid_field *field, struct hid_usage *usage, |
264 | unsigned long **bit, int *max) | 287 | unsigned long **bit, int *max) |
265 | { | 288 | { |
266 | struct mt_device *td = hid_get_drvdata(hdev); | 289 | struct mt_device *td = hid_get_drvdata(hdev); |
267 | struct mt_class *cls = &td->mtclass; | 290 | struct mt_class *cls = &td->mtclass; |
291 | int code; | ||
268 | 292 | ||
269 | /* Only map fields from TouchScreen or TouchPad collections. | 293 | /* Only map fields from TouchScreen or TouchPad collections. |
270 | * We need to ignore fields that belong to other collections | 294 | * We need to ignore fields that belong to other collections |
271 | * such as Mouse that might have the same GenericDesktop usages. */ | 295 | * such as Mouse that might have the same GenericDesktop usages. */ |
272 | if (field->application == HID_DG_TOUCHSCREEN) | 296 | if (field->application == HID_DG_TOUCHSCREEN) |
273 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); | 297 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); |
274 | else if (field->application == HID_DG_TOUCHPAD) | 298 | else if (field->application != HID_DG_TOUCHPAD) |
275 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
276 | else | ||
277 | return 0; | 299 | return 0; |
278 | 300 | ||
301 | /* In case of an indirect device (touchpad), we need to add | ||
302 | * specific BTN_TOOL_* to be handled by the synaptics xorg | ||
303 | * driver. | ||
304 | * We also consider that touchscreens providing buttons are touchpads. | ||
305 | */ | ||
306 | if (field->application == HID_DG_TOUCHPAD || | ||
307 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || | ||
308 | cls->is_indirect) { | ||
309 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
310 | set_bit(BTN_TOOL_FINGER, hi->input->keybit); | ||
311 | set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); | ||
312 | set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); | ||
313 | set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); | ||
314 | } | ||
315 | |||
279 | /* eGalax devices provide a Digitizer.Stylus input which overrides | 316 | /* eGalax devices provide a Digitizer.Stylus input which overrides |
280 | * the correct Digitizers.Finger X/Y ranges. | 317 | * the correct Digitizers.Finger X/Y ranges. |
281 | * Let's just ignore this input. */ | 318 | * Let's just ignore this input. */ |
@@ -293,10 +330,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
293 | cls->sn_move); | 330 | cls->sn_move); |
294 | /* touchscreen emulation */ | 331 | /* touchscreen emulation */ |
295 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 332 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
296 | if (td->last_mt_collection == usage->collection_index) { | 333 | set_last_slot_field(usage, td, hi); |
297 | td->last_slot_field = usage->hid; | 334 | td->last_field_index = field->index; |
298 | td->last_field_index = field->index; | ||
299 | } | ||
300 | return 1; | 335 | return 1; |
301 | case HID_GD_Y: | 336 | case HID_GD_Y: |
302 | hid_map_usage(hi, usage, bit, max, | 337 | hid_map_usage(hi, usage, bit, max, |
@@ -305,10 +340,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
305 | cls->sn_move); | 340 | cls->sn_move); |
306 | /* touchscreen emulation */ | 341 | /* touchscreen emulation */ |
307 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 342 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
308 | if (td->last_mt_collection == usage->collection_index) { | 343 | set_last_slot_field(usage, td, hi); |
309 | td->last_slot_field = usage->hid; | 344 | td->last_field_index = field->index; |
310 | td->last_field_index = field->index; | ||
311 | } | ||
312 | return 1; | 345 | return 1; |
313 | } | 346 | } |
314 | return 0; | 347 | return 0; |
@@ -316,24 +349,18 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
316 | case HID_UP_DIGITIZER: | 349 | case HID_UP_DIGITIZER: |
317 | switch (usage->hid) { | 350 | switch (usage->hid) { |
318 | case HID_DG_INRANGE: | 351 | case HID_DG_INRANGE: |
319 | if (td->last_mt_collection == usage->collection_index) { | 352 | set_last_slot_field(usage, td, hi); |
320 | td->last_slot_field = usage->hid; | 353 | td->last_field_index = field->index; |
321 | td->last_field_index = field->index; | ||
322 | } | ||
323 | return 1; | 354 | return 1; |
324 | case HID_DG_CONFIDENCE: | 355 | case HID_DG_CONFIDENCE: |
325 | if (td->last_mt_collection == usage->collection_index) { | 356 | set_last_slot_field(usage, td, hi); |
326 | td->last_slot_field = usage->hid; | 357 | td->last_field_index = field->index; |
327 | td->last_field_index = field->index; | ||
328 | } | ||
329 | return 1; | 358 | return 1; |
330 | case HID_DG_TIPSWITCH: | 359 | case HID_DG_TIPSWITCH: |
331 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 360 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
332 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 361 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
333 | if (td->last_mt_collection == usage->collection_index) { | 362 | set_last_slot_field(usage, td, hi); |
334 | td->last_slot_field = usage->hid; | 363 | td->last_field_index = field->index; |
335 | td->last_field_index = field->index; | ||
336 | } | ||
337 | return 1; | 364 | return 1; |
338 | case HID_DG_CONTACTID: | 365 | case HID_DG_CONTACTID: |
339 | if (!td->maxcontacts) | 366 | if (!td->maxcontacts) |
@@ -341,17 +368,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
341 | input_mt_init_slots(hi->input, td->maxcontacts); | 368 | input_mt_init_slots(hi->input, td->maxcontacts); |
342 | td->last_slot_field = usage->hid; | 369 | td->last_slot_field = usage->hid; |
343 | td->last_field_index = field->index; | 370 | td->last_field_index = field->index; |
344 | td->last_mt_collection = usage->collection_index; | 371 | td->touches_by_report++; |
345 | return 1; | 372 | return 1; |
346 | case HID_DG_WIDTH: | 373 | case HID_DG_WIDTH: |
347 | hid_map_usage(hi, usage, bit, max, | 374 | hid_map_usage(hi, usage, bit, max, |
348 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 375 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
349 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 376 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
350 | cls->sn_width); | 377 | cls->sn_width); |
351 | if (td->last_mt_collection == usage->collection_index) { | 378 | set_last_slot_field(usage, td, hi); |
352 | td->last_slot_field = usage->hid; | 379 | td->last_field_index = field->index; |
353 | td->last_field_index = field->index; | ||
354 | } | ||
355 | return 1; | 380 | return 1; |
356 | case HID_DG_HEIGHT: | 381 | case HID_DG_HEIGHT: |
357 | hid_map_usage(hi, usage, bit, max, | 382 | hid_map_usage(hi, usage, bit, max, |
@@ -360,10 +385,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
360 | cls->sn_height); | 385 | cls->sn_height); |
361 | input_set_abs_params(hi->input, | 386 | input_set_abs_params(hi->input, |
362 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 387 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
363 | if (td->last_mt_collection == usage->collection_index) { | 388 | set_last_slot_field(usage, td, hi); |
364 | td->last_slot_field = usage->hid; | 389 | td->last_field_index = field->index; |
365 | td->last_field_index = field->index; | ||
366 | } | ||
367 | return 1; | 390 | return 1; |
368 | case HID_DG_TIPPRESSURE: | 391 | case HID_DG_TIPPRESSURE: |
369 | hid_map_usage(hi, usage, bit, max, | 392 | hid_map_usage(hi, usage, bit, max, |
@@ -373,25 +396,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
373 | /* touchscreen emulation */ | 396 | /* touchscreen emulation */ |
374 | set_abs(hi->input, ABS_PRESSURE, field, | 397 | set_abs(hi->input, ABS_PRESSURE, field, |
375 | cls->sn_pressure); | 398 | cls->sn_pressure); |
376 | if (td->last_mt_collection == usage->collection_index) { | 399 | set_last_slot_field(usage, td, hi); |
377 | td->last_slot_field = usage->hid; | 400 | td->last_field_index = field->index; |
378 | td->last_field_index = field->index; | ||
379 | } | ||
380 | return 1; | 401 | return 1; |
381 | case HID_DG_CONTACTCOUNT: | 402 | case HID_DG_CONTACTCOUNT: |
382 | if (td->last_mt_collection == usage->collection_index) | 403 | td->last_field_index = field->index; |
383 | td->last_field_index = field->index; | ||
384 | return 1; | 404 | return 1; |
385 | case HID_DG_CONTACTMAX: | 405 | case HID_DG_CONTACTMAX: |
386 | /* we don't set td->last_slot_field as contactcount and | 406 | /* we don't set td->last_slot_field as contactcount and |
387 | * contact max are global to the report */ | 407 | * contact max are global to the report */ |
388 | if (td->last_mt_collection == usage->collection_index) | 408 | td->last_field_index = field->index; |
389 | td->last_field_index = field->index; | ||
390 | return -1; | 409 | return -1; |
391 | } | 410 | } |
411 | case HID_DG_TOUCH: | ||
412 | /* Legacy devices use TIPSWITCH and not TOUCH. | ||
413 | * Let's just ignore this field. */ | ||
414 | return -1; | ||
392 | /* let hid-input decide for the others */ | 415 | /* let hid-input decide for the others */ |
393 | return 0; | 416 | return 0; |
394 | 417 | ||
418 | case HID_UP_BUTTON: | ||
419 | code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); | ||
420 | hid_map_usage(hi, usage, bit, max, EV_KEY, code); | ||
421 | input_set_capability(hi->input, EV_KEY, code); | ||
422 | return 1; | ||
423 | |||
395 | case 0xff000000: | 424 | case 0xff000000: |
396 | /* we do not want to map these: no input-oriented meaning */ | 425 | /* we do not want to map these: no input-oriented meaning */ |
397 | return -1; | 426 | return -1; |
@@ -538,15 +567,17 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
538 | if (value) | 567 | if (value) |
539 | td->num_expected = value; | 568 | td->num_expected = value; |
540 | break; | 569 | break; |
570 | case HID_DG_TOUCH: | ||
571 | /* do nothing */ | ||
572 | break; | ||
541 | 573 | ||
542 | default: | 574 | default: |
543 | /* fallback to the generic hidinput handling */ | 575 | /* fallback to the generic hidinput handling */ |
544 | return 0; | 576 | return 0; |
545 | } | 577 | } |
546 | 578 | ||
547 | if (usage->hid == td->last_slot_field) { | 579 | if (usage->hid == td->last_slot_field) |
548 | mt_complete_slot(td); | 580 | mt_complete_slot(td); |
549 | } | ||
550 | 581 | ||
551 | if (field->index == td->last_field_index | 582 | if (field->index == td->last_field_index |
552 | && td->num_received >= td->num_expected) | 583 | && td->num_received >= td->num_expected) |
@@ -578,16 +609,44 @@ static void mt_set_input_mode(struct hid_device *hdev) | |||
578 | } | 609 | } |
579 | } | 610 | } |
580 | 611 | ||
612 | static void mt_set_maxcontacts(struct hid_device *hdev) | ||
613 | { | ||
614 | struct mt_device *td = hid_get_drvdata(hdev); | ||
615 | struct hid_report *r; | ||
616 | struct hid_report_enum *re; | ||
617 | int fieldmax, max; | ||
618 | |||
619 | if (td->maxcontact_report_id < 0) | ||
620 | return; | ||
621 | |||
622 | if (!td->mtclass.maxcontacts) | ||
623 | return; | ||
624 | |||
625 | re = &hdev->report_enum[HID_FEATURE_REPORT]; | ||
626 | r = re->report_id_hash[td->maxcontact_report_id]; | ||
627 | if (r) { | ||
628 | max = td->mtclass.maxcontacts; | ||
629 | fieldmax = r->field[0]->logical_maximum; | ||
630 | max = min(fieldmax, max); | ||
631 | if (r->field[0]->value[0] != max) { | ||
632 | r->field[0]->value[0] = max; | ||
633 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | |||
581 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 638 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
582 | { | 639 | { |
583 | int ret, i; | 640 | int ret, i; |
584 | struct mt_device *td; | 641 | struct mt_device *td; |
585 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ | 642 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ |
586 | 643 | ||
587 | for (i = 0; mt_classes[i].name ; i++) { | 644 | if (id) { |
588 | if (id->driver_data == mt_classes[i].name) { | 645 | for (i = 0; mt_classes[i].name ; i++) { |
589 | mtclass = &(mt_classes[i]); | 646 | if (id->driver_data == mt_classes[i].name) { |
590 | break; | 647 | mtclass = &(mt_classes[i]); |
648 | break; | ||
649 | } | ||
591 | } | 650 | } |
592 | } | 651 | } |
593 | 652 | ||
@@ -595,6 +654,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
595 | * that emit events over several HID messages. | 654 | * that emit events over several HID messages. |
596 | */ | 655 | */ |
597 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 656 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
657 | hdev->quirks &= ~HID_QUIRK_MULTITOUCH; | ||
598 | 658 | ||
599 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); | 659 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
600 | if (!td) { | 660 | if (!td) { |
@@ -603,7 +663,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
603 | } | 663 | } |
604 | td->mtclass = *mtclass; | 664 | td->mtclass = *mtclass; |
605 | td->inputmode = -1; | 665 | td->inputmode = -1; |
606 | td->last_mt_collection = -1; | 666 | td->maxcontact_report_id = -1; |
607 | hid_set_drvdata(hdev, td); | 667 | hid_set_drvdata(hdev, td); |
608 | 668 | ||
609 | ret = hid_parse(hdev); | 669 | ret = hid_parse(hdev); |
@@ -614,6 +674,15 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
614 | if (ret) | 674 | if (ret) |
615 | goto fail; | 675 | goto fail; |
616 | 676 | ||
677 | if (!id && td->touches_by_report == 1) { | ||
678 | /* the device has been sent by hid-generic */ | ||
679 | mtclass = &td->mtclass; | ||
680 | mtclass->quirks |= MT_QUIRK_ALWAYS_VALID; | ||
681 | mtclass->quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | ||
682 | mtclass->quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | ||
683 | mtclass->quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | ||
684 | } | ||
685 | |||
617 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | 686 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), |
618 | GFP_KERNEL); | 687 | GFP_KERNEL); |
619 | if (!td->slots) { | 688 | if (!td->slots) { |
@@ -625,6 +694,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
625 | 694 | ||
626 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); | 695 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); |
627 | 696 | ||
697 | mt_set_maxcontacts(hdev); | ||
628 | mt_set_input_mode(hdev); | 698 | mt_set_input_mode(hdev); |
629 | 699 | ||
630 | return 0; | 700 | return 0; |
@@ -637,6 +707,7 @@ fail: | |||
637 | #ifdef CONFIG_PM | 707 | #ifdef CONFIG_PM |
638 | static int mt_reset_resume(struct hid_device *hdev) | 708 | static int mt_reset_resume(struct hid_device *hdev) |
639 | { | 709 | { |
710 | mt_set_maxcontacts(hdev); | ||
640 | mt_set_input_mode(hdev); | 711 | mt_set_input_mode(hdev); |
641 | return 0; | 712 | return 0; |
642 | } | 713 | } |
@@ -674,6 +745,9 @@ static const struct hid_device_id mt_devices[] = { | |||
674 | { .driver_data = MT_CLS_SERIAL, | 745 | { .driver_data = MT_CLS_SERIAL, |
675 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | 746 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, |
676 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, | 747 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, |
748 | { .driver_data = MT_CLS_SERIAL, | ||
749 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | ||
750 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, | ||
677 | 751 | ||
678 | /* Cando panels */ | 752 | /* Cando panels */ |
679 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 753 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
@@ -716,12 +790,30 @@ static const struct hid_device_id mt_devices[] = { | |||
716 | { .driver_data = MT_CLS_EGALAX, | 790 | { .driver_data = MT_CLS_EGALAX, |
717 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 791 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
718 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | 792 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, |
793 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
794 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
795 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, | ||
796 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
797 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
798 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | ||
799 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
800 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
801 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | ||
802 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
803 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
804 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, | ||
719 | { .driver_data = MT_CLS_EGALAX, | 805 | { .driver_data = MT_CLS_EGALAX, |
720 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 806 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
721 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | 807 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, |
808 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
809 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
810 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, | ||
722 | { .driver_data = MT_CLS_EGALAX, | 811 | { .driver_data = MT_CLS_EGALAX, |
723 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 812 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
724 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | 813 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, |
814 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
815 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
816 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, | ||
725 | { .driver_data = MT_CLS_EGALAX, | 817 | { .driver_data = MT_CLS_EGALAX, |
726 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 818 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
727 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, | 819 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, |
@@ -730,6 +822,9 @@ static const struct hid_device_id mt_devices[] = { | |||
730 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, | 822 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, |
731 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 823 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
732 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 824 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
825 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) }, | ||
826 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
827 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
733 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | 828 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
734 | 829 | ||
735 | /* Elo TouchSystems IntelliTouch Plus panel */ | 830 | /* Elo TouchSystems IntelliTouch Plus panel */ |
@@ -756,6 +851,9 @@ static const struct hid_device_id mt_devices[] = { | |||
756 | { .driver_data = MT_CLS_SERIAL, | 851 | { .driver_data = MT_CLS_SERIAL, |
757 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | 852 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, |
758 | USB_DEVICE_ID_IDEACOM_IDC6650) }, | 853 | USB_DEVICE_ID_IDEACOM_IDC6650) }, |
854 | { .driver_data = MT_CLS_SERIAL, | ||
855 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | ||
856 | USB_DEVICE_ID_IDEACOM_IDC6651) }, | ||
759 | 857 | ||
760 | /* Ilitek dual touch panel */ | 858 | /* Ilitek dual touch panel */ |
761 | { .driver_data = MT_CLS_DEFAULT, | 859 | { .driver_data = MT_CLS_DEFAULT, |
@@ -791,6 +889,14 @@ static const struct hid_device_id mt_devices[] = { | |||
791 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, | 889 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, |
792 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | 890 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, |
793 | 891 | ||
892 | /* Panasonic panels */ | ||
893 | { .driver_data = MT_CLS_PANASONIC, | ||
894 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | ||
895 | USB_DEVICE_ID_PANABOARD_UBT780) }, | ||
896 | { .driver_data = MT_CLS_PANASONIC, | ||
897 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | ||
898 | USB_DEVICE_ID_PANABOARD_UBT880) }, | ||
899 | |||
794 | /* PenMount panels */ | 900 | /* PenMount panels */ |
795 | { .driver_data = MT_CLS_CONFIDENCE, | 901 | { .driver_data = MT_CLS_CONFIDENCE, |
796 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, | 902 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, |
@@ -837,6 +943,11 @@ static const struct hid_device_id mt_devices[] = { | |||
837 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, | 943 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, |
838 | USB_DEVICE_ID_MTP_SITRONIX)}, | 944 | USB_DEVICE_ID_MTP_SITRONIX)}, |
839 | 945 | ||
946 | /* TopSeed panels */ | ||
947 | { .driver_data = MT_CLS_TOPSEED, | ||
948 | HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, | ||
949 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, | ||
950 | |||
840 | /* Touch International panels */ | 951 | /* Touch International panels */ |
841 | { .driver_data = MT_CLS_DEFAULT, | 952 | { .driver_data = MT_CLS_DEFAULT, |
842 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, | 953 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index f779009104eb..b71b77ab0dc7 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c | |||
@@ -90,7 +90,7 @@ static const char longname[] = "Prodikeys PC-MIDI Keyboard"; | |||
90 | 90 | ||
91 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 91 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
92 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 92 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
93 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 93 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
94 | 94 | ||
95 | module_param_array(index, int, NULL, 0444); | 95 | module_param_array(index, int, NULL, 0444); |
96 | module_param_array(id, charp, NULL, 0444); | 96 | module_param_array(id, charp, NULL, 0444); |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index f2183486a9b6..acab74cde727 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -49,12 +49,14 @@ static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; | |||
49 | 49 | ||
50 | static enum power_supply_property wacom_battery_props[] = { | 50 | static enum power_supply_property wacom_battery_props[] = { |
51 | POWER_SUPPLY_PROP_PRESENT, | 51 | POWER_SUPPLY_PROP_PRESENT, |
52 | POWER_SUPPLY_PROP_CAPACITY | 52 | POWER_SUPPLY_PROP_CAPACITY, |
53 | POWER_SUPPLY_PROP_SCOPE, | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | static enum power_supply_property wacom_ac_props[] = { | 56 | static enum power_supply_property wacom_ac_props[] = { |
56 | POWER_SUPPLY_PROP_PRESENT, | 57 | POWER_SUPPLY_PROP_PRESENT, |
57 | POWER_SUPPLY_PROP_ONLINE | 58 | POWER_SUPPLY_PROP_ONLINE, |
59 | POWER_SUPPLY_PROP_SCOPE, | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | static int wacom_battery_get_property(struct power_supply *psy, | 62 | static int wacom_battery_get_property(struct power_supply *psy, |
@@ -70,6 +72,9 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
70 | case POWER_SUPPLY_PROP_PRESENT: | 72 | case POWER_SUPPLY_PROP_PRESENT: |
71 | val->intval = 1; | 73 | val->intval = 1; |
72 | break; | 74 | break; |
75 | case POWER_SUPPLY_PROP_SCOPE: | ||
76 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
77 | break; | ||
73 | case POWER_SUPPLY_PROP_CAPACITY: | 78 | case POWER_SUPPLY_PROP_CAPACITY: |
74 | /* show 100% battery capacity when charging */ | 79 | /* show 100% battery capacity when charging */ |
75 | if (power_state == 0) | 80 | if (power_state == 0) |
@@ -101,6 +106,9 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
101 | else | 106 | else |
102 | val->intval = 0; | 107 | val->intval = 0; |
103 | break; | 108 | break; |
109 | case POWER_SUPPLY_PROP_SCOPE: | ||
110 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
111 | break; | ||
104 | default: | 112 | default: |
105 | ret = -EINVAL; | 113 | ret = -EINVAL; |
106 | break; | 114 | break; |
@@ -523,6 +531,7 @@ static int wacom_probe(struct hid_device *hdev, | |||
523 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 531 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; |
524 | wdata->battery.use_for_apm = 0; | 532 | wdata->battery.use_for_apm = 0; |
525 | 533 | ||
534 | |||
526 | ret = power_supply_register(&hdev->dev, &wdata->battery); | 535 | ret = power_supply_register(&hdev->dev, &wdata->battery); |
527 | if (ret) { | 536 | if (ret) { |
528 | hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", | 537 | hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", |
@@ -530,6 +539,8 @@ static int wacom_probe(struct hid_device *hdev, | |||
530 | goto err_battery; | 539 | goto err_battery; |
531 | } | 540 | } |
532 | 541 | ||
542 | power_supply_powers(&wdata->battery, &hdev->dev); | ||
543 | |||
533 | wdata->ac.properties = wacom_ac_props; | 544 | wdata->ac.properties = wacom_ac_props; |
534 | wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props); | 545 | wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props); |
535 | wdata->ac.get_property = wacom_ac_get_property; | 546 | wdata->ac.get_property = wacom_ac_get_property; |
@@ -543,6 +554,8 @@ static int wacom_probe(struct hid_device *hdev, | |||
543 | "can't create ac battery attribute, err: %d\n", ret); | 554 | "can't create ac battery attribute, err: %d\n", ret); |
544 | goto err_ac; | 555 | goto err_ac; |
545 | } | 556 | } |
557 | |||
558 | power_supply_powers(&wdata->ac, &hdev->dev); | ||
546 | #endif | 559 | #endif |
547 | return 0; | 560 | return 0; |
548 | 561 | ||
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 61881b35c670..cac3589b1ed5 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
@@ -52,7 +52,8 @@ static __u16 wiiproto_keymap[] = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | static enum power_supply_property wiimote_battery_props[] = { | 54 | static enum power_supply_property wiimote_battery_props[] = { |
55 | POWER_SUPPLY_PROP_CAPACITY | 55 | POWER_SUPPLY_PROP_CAPACITY, |
56 | POWER_SUPPLY_PROP_SCOPE, | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, | 59 | static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, |
@@ -402,6 +403,11 @@ static int wiimote_battery_get_property(struct power_supply *psy, | |||
402 | int ret = 0, state; | 403 | int ret = 0, state; |
403 | unsigned long flags; | 404 | unsigned long flags; |
404 | 405 | ||
406 | if (psp == POWER_SUPPLY_PROP_SCOPE) { | ||
407 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | ||
408 | return 0; | ||
409 | } | ||
410 | |||
405 | ret = wiimote_cmd_acquire(wdata); | 411 | ret = wiimote_cmd_acquire(wdata); |
406 | if (ret) | 412 | if (ret) |
407 | return ret; | 413 | return ret; |
@@ -1226,6 +1232,8 @@ static int wiimote_hid_probe(struct hid_device *hdev, | |||
1226 | goto err_battery; | 1232 | goto err_battery; |
1227 | } | 1233 | } |
1228 | 1234 | ||
1235 | power_supply_powers(&wdata->battery, &hdev->dev); | ||
1236 | |||
1229 | ret = wiimote_leds_create(wdata); | 1237 | ret = wiimote_leds_create(wdata); |
1230 | if (ret) | 1238 | if (ret) |
1231 | goto err_free; | 1239 | goto err_free; |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index c831af937481..0dd0bebac69f 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -54,6 +54,7 @@ static const struct hid_blacklist { | |||
54 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 54 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, | 55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, |
56 | 56 | ||
57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, | ||
57 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
@@ -73,6 +74,7 @@ static const struct hid_blacklist { | |||
73 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, | 74 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, |
74 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 75 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
75 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, | 76 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, |
77 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, | ||
76 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 78 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
77 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, | 79 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, |
78 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, | 80 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 7c297d305d5d..b1ec0e2aeb57 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -922,11 +922,11 @@ void hiddev_disconnect(struct hid_device *hid) | |||
922 | struct hiddev *hiddev = hid->hiddev; | 922 | struct hiddev *hiddev = hid->hiddev; |
923 | struct usbhid_device *usbhid = hid->driver_data; | 923 | struct usbhid_device *usbhid = hid->driver_data; |
924 | 924 | ||
925 | usb_deregister_dev(usbhid->intf, &hiddev_class); | ||
926 | |||
925 | mutex_lock(&hiddev->existancelock); | 927 | mutex_lock(&hiddev->existancelock); |
926 | hiddev->exist = 0; | 928 | hiddev->exist = 0; |
927 | 929 | ||
928 | usb_deregister_dev(usbhid->intf, &hiddev_class); | ||
929 | |||
930 | if (hiddev->open) { | 930 | if (hiddev->open) { |
931 | mutex_unlock(&hiddev->existancelock); | 931 | mutex_unlock(&hiddev->existancelock); |
932 | usbhid_close(hiddev->hid); | 932 | usbhid_close(hiddev->hid); |