diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-11 15:31:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-11 15:31:09 -0400 |
commit | 1c74a7f812b135d3df41d7c3671b647aed6467bf (patch) | |
tree | ed0a98bf45ed30db3a90ab8f2c92d82d8af80d2b | |
parent | 6c6563a4894238a3ed9c40601018816b60c31ec4 (diff) | |
parent | 326ea2a90500fe4add86c5fb95d914d46910e780 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina:
- fix for how scaling linearization is computed in wiimote driver, by
Cyan Ogilvie
- endless retry loop fix in generic USB HID core reset-resume handling,
by Alan Stern
- two functional fixes affecting particular devices, and oops fix for
wacom driver, by Jason Gerecke
- multitouch slot numbering fix from Gabriele Mazzotta
- a couple more small fixes on top
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: wacom: Support switching from vendor-defined device mode on G9 and G11
HID: wacom: Initialize hid_data.inputmode to -1
HID: microsoft: add support for 3 more devices
HID: multitouch: Synchronize MT frame on reset_resume
HID: wacom: fix Bamboo ONE oops
HID: lenovo: Don't use stack variables for DMA buffers
HID: usbhid: fix inconsistent reset/resume/reset-resume behavior
HID: wiimote: Fix wiimote mp scale linearization
-rw-r--r-- | drivers/hid/hid-core.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-lenovo.c | 16 | ||||
-rw-r--r-- | drivers/hid/hid-microsoft.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-multitouch.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-modules.c | 14 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 73 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 102 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 11 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 8 |
10 files changed, 164 insertions, 73 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bdb8cc89cacc..4f9c5c6deaed 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1979,6 +1979,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1979 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, | 1979 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, |
1980 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, | 1980 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, |
1981 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, | 1981 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, |
1982 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) }, | ||
1983 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) }, | ||
1984 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) }, | ||
1982 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, | 1985 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, |
1983 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1986 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1984 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, | 1987 | { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5c0e43ed5c53..c6eaff5f8845 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -676,6 +676,7 @@ | |||
676 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 676 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
677 | #define USB_DEVICE_ID_MS_OFFICE_KB 0x0048 | 677 | #define USB_DEVICE_ID_MS_OFFICE_KB 0x0048 |
678 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | 678 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d |
679 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K 0x00b4 | ||
679 | #define USB_DEVICE_ID_MS_NE4K 0x00db | 680 | #define USB_DEVICE_ID_MS_NE4K 0x00db |
680 | #define USB_DEVICE_ID_MS_NE4K_JP 0x00dc | 681 | #define USB_DEVICE_ID_MS_NE4K_JP 0x00dc |
681 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | 682 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 |
@@ -683,6 +684,8 @@ | |||
683 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 684 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
684 | #define USB_DEVICE_ID_MS_NE7K 0x071d | 685 | #define USB_DEVICE_ID_MS_NE7K 0x071d |
685 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 | 686 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 |
687 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732 | ||
688 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600 0x0750 | ||
686 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c | 689 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c |
687 | #define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3 | 690 | #define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3 |
688 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 | 691 | #define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799 |
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 0125e356bd8d..1ac4ff4d57a6 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c | |||
@@ -184,21 +184,31 @@ static int lenovo_send_cmd_cptkbd(struct hid_device *hdev, | |||
184 | unsigned char byte2, unsigned char byte3) | 184 | unsigned char byte2, unsigned char byte3) |
185 | { | 185 | { |
186 | int ret; | 186 | int ret; |
187 | unsigned char buf[] = {0x18, byte2, byte3}; | 187 | unsigned char *buf; |
188 | |||
189 | buf = kzalloc(3, GFP_KERNEL); | ||
190 | if (!buf) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | buf[0] = 0x18; | ||
194 | buf[1] = byte2; | ||
195 | buf[2] = byte3; | ||
188 | 196 | ||
189 | switch (hdev->product) { | 197 | switch (hdev->product) { |
190 | case USB_DEVICE_ID_LENOVO_CUSBKBD: | 198 | case USB_DEVICE_ID_LENOVO_CUSBKBD: |
191 | ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf), | 199 | ret = hid_hw_raw_request(hdev, 0x13, buf, 3, |
192 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | 200 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); |
193 | break; | 201 | break; |
194 | case USB_DEVICE_ID_LENOVO_CBTKBD: | 202 | case USB_DEVICE_ID_LENOVO_CBTKBD: |
195 | ret = hid_hw_output_report(hdev, buf, sizeof(buf)); | 203 | ret = hid_hw_output_report(hdev, buf, 3); |
196 | break; | 204 | break; |
197 | default: | 205 | default: |
198 | ret = -EINVAL; | 206 | ret = -EINVAL; |
199 | break; | 207 | break; |
200 | } | 208 | } |
201 | 209 | ||
210 | kfree(buf); | ||
211 | |||
202 | return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ | 212 | return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ |
203 | } | 213 | } |
204 | 214 | ||
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 75cd3bc59c54..e924d555536c 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -272,6 +272,12 @@ static const struct hid_device_id ms_devices[] = { | |||
272 | .driver_data = MS_PRESENTER }, | 272 | .driver_data = MS_PRESENTER }, |
273 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), | 273 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), |
274 | .driver_data = MS_ERGONOMY | MS_RDESC_3K }, | 274 | .driver_data = MS_ERGONOMY | MS_RDESC_3K }, |
275 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K), | ||
276 | .driver_data = MS_ERGONOMY }, | ||
277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600), | ||
278 | .driver_data = MS_ERGONOMY }, | ||
279 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1), | ||
280 | .driver_data = MS_ERGONOMY }, | ||
275 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), | 281 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), |
276 | .driver_data = MS_NOGET }, | 282 | .driver_data = MS_NOGET }, |
277 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 283 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 25d3c4330bf6..c741f5e50a66 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1169,6 +1169,7 @@ static void mt_release_contacts(struct hid_device *hid) | |||
1169 | MT_TOOL_FINGER, | 1169 | MT_TOOL_FINGER, |
1170 | false); | 1170 | false); |
1171 | } | 1171 | } |
1172 | input_mt_sync_frame(input_dev); | ||
1172 | input_sync(input_dev); | 1173 | input_sync(input_dev); |
1173 | } | 1174 | } |
1174 | } | 1175 | } |
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 4390eee2ce84..c830ed39348f 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
@@ -2049,9 +2049,11 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) | |||
2049 | * -----+------------------------------+-----+-----+ | 2049 | * -----+------------------------------+-----+-----+ |
2050 | * The single bits Yaw, Roll, Pitch in the lower right corner specify | 2050 | * The single bits Yaw, Roll, Pitch in the lower right corner specify |
2051 | * whether the wiimote is rotating fast (0) or slow (1). Speed for slow | 2051 | * whether the wiimote is rotating fast (0) or slow (1). Speed for slow |
2052 | * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a | 2052 | * roation is 8192/440 units / deg/s and for fast rotation 8192/2000 |
2053 | * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast | 2053 | * units / deg/s. To get a linear scale for fast rotation we multiply |
2054 | * and 9 for slow. | 2054 | * by 2000/440 = ~4.5454 and scale both fast and slow by 9 to match the |
2055 | * previous scale reported by this driver. | ||
2056 | * This leaves a linear scale with 8192*9/440 (~167.564) units / deg/s. | ||
2055 | * If the wiimote is not rotating the sensor reports 2^13 = 8192. | 2057 | * If the wiimote is not rotating the sensor reports 2^13 = 8192. |
2056 | * Ext specifies whether an extension is connected to the motionp. | 2058 | * Ext specifies whether an extension is connected to the motionp. |
2057 | * which is parsed by wiimote-core. | 2059 | * which is parsed by wiimote-core. |
@@ -2070,15 +2072,15 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) | |||
2070 | z -= 8192; | 2072 | z -= 8192; |
2071 | 2073 | ||
2072 | if (!(ext[3] & 0x02)) | 2074 | if (!(ext[3] & 0x02)) |
2073 | x *= 18; | 2075 | x = (x * 2000 * 9) / 440; |
2074 | else | 2076 | else |
2075 | x *= 9; | 2077 | x *= 9; |
2076 | if (!(ext[4] & 0x02)) | 2078 | if (!(ext[4] & 0x02)) |
2077 | y *= 18; | 2079 | y = (y * 2000 * 9) / 440; |
2078 | else | 2080 | else |
2079 | y *= 9; | 2081 | y *= 9; |
2080 | if (!(ext[3] & 0x01)) | 2082 | if (!(ext[3] & 0x01)) |
2081 | z *= 18; | 2083 | z = (z * 2000 * 9) / 440; |
2082 | else | 2084 | else |
2083 | z *= 9; | 2085 | z *= 9; |
2084 | 2086 | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ad71160b9ea4..ae83af649a60 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -951,14 +951,6 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count) | |||
951 | return ret; | 951 | return ret; |
952 | } | 952 | } |
953 | 953 | ||
954 | static void usbhid_restart_queues(struct usbhid_device *usbhid) | ||
955 | { | ||
956 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) | ||
957 | usbhid_restart_out_queue(usbhid); | ||
958 | if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) | ||
959 | usbhid_restart_ctrl_queue(usbhid); | ||
960 | } | ||
961 | |||
962 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | 954 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
963 | { | 955 | { |
964 | struct usbhid_device *usbhid = hid->driver_data; | 956 | struct usbhid_device *usbhid = hid->driver_data; |
@@ -1404,6 +1396,37 @@ static void hid_cease_io(struct usbhid_device *usbhid) | |||
1404 | usb_kill_urb(usbhid->urbout); | 1396 | usb_kill_urb(usbhid->urbout); |
1405 | } | 1397 | } |
1406 | 1398 | ||
1399 | static void hid_restart_io(struct hid_device *hid) | ||
1400 | { | ||
1401 | struct usbhid_device *usbhid = hid->driver_data; | ||
1402 | int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl); | ||
1403 | int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl); | ||
1404 | |||
1405 | spin_lock_irq(&usbhid->lock); | ||
1406 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | ||
1407 | usbhid_mark_busy(usbhid); | ||
1408 | |||
1409 | if (clear_halt || reset_pending) | ||
1410 | schedule_work(&usbhid->reset_work); | ||
1411 | usbhid->retry_delay = 0; | ||
1412 | spin_unlock_irq(&usbhid->lock); | ||
1413 | |||
1414 | if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl)) | ||
1415 | return; | ||
1416 | |||
1417 | if (!clear_halt) { | ||
1418 | if (hid_start_in(hid) < 0) | ||
1419 | hid_io_error(hid); | ||
1420 | } | ||
1421 | |||
1422 | spin_lock_irq(&usbhid->lock); | ||
1423 | if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) | ||
1424 | usbhid_restart_out_queue(usbhid); | ||
1425 | if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) | ||
1426 | usbhid_restart_ctrl_queue(usbhid); | ||
1427 | spin_unlock_irq(&usbhid->lock); | ||
1428 | } | ||
1429 | |||
1407 | /* Treat USB reset pretty much the same as suspend/resume */ | 1430 | /* Treat USB reset pretty much the same as suspend/resume */ |
1408 | static int hid_pre_reset(struct usb_interface *intf) | 1431 | static int hid_pre_reset(struct usb_interface *intf) |
1409 | { | 1432 | { |
@@ -1453,14 +1476,14 @@ static int hid_post_reset(struct usb_interface *intf) | |||
1453 | return 1; | 1476 | return 1; |
1454 | } | 1477 | } |
1455 | 1478 | ||
1479 | /* No need to do another reset or clear a halted endpoint */ | ||
1456 | spin_lock_irq(&usbhid->lock); | 1480 | spin_lock_irq(&usbhid->lock); |
1457 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 1481 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
1482 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); | ||
1458 | spin_unlock_irq(&usbhid->lock); | 1483 | spin_unlock_irq(&usbhid->lock); |
1459 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); | 1484 | hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); |
1460 | status = hid_start_in(hid); | 1485 | |
1461 | if (status < 0) | 1486 | hid_restart_io(hid); |
1462 | hid_io_error(hid); | ||
1463 | usbhid_restart_queues(usbhid); | ||
1464 | 1487 | ||
1465 | return 0; | 1488 | return 0; |
1466 | } | 1489 | } |
@@ -1483,25 +1506,9 @@ void usbhid_put_power(struct hid_device *hid) | |||
1483 | #ifdef CONFIG_PM | 1506 | #ifdef CONFIG_PM |
1484 | static int hid_resume_common(struct hid_device *hid, bool driver_suspended) | 1507 | static int hid_resume_common(struct hid_device *hid, bool driver_suspended) |
1485 | { | 1508 | { |
1486 | struct usbhid_device *usbhid = hid->driver_data; | 1509 | int status = 0; |
1487 | int status; | ||
1488 | |||
1489 | spin_lock_irq(&usbhid->lock); | ||
1490 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | ||
1491 | usbhid_mark_busy(usbhid); | ||
1492 | |||
1493 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) || | ||
1494 | test_bit(HID_RESET_PENDING, &usbhid->iofl)) | ||
1495 | schedule_work(&usbhid->reset_work); | ||
1496 | usbhid->retry_delay = 0; | ||
1497 | |||
1498 | usbhid_restart_queues(usbhid); | ||
1499 | spin_unlock_irq(&usbhid->lock); | ||
1500 | |||
1501 | status = hid_start_in(hid); | ||
1502 | if (status < 0) | ||
1503 | hid_io_error(hid); | ||
1504 | 1510 | ||
1511 | hid_restart_io(hid); | ||
1505 | if (driver_suspended && hid->driver && hid->driver->resume) | 1512 | if (driver_suspended && hid->driver && hid->driver->resume) |
1506 | status = hid->driver->resume(hid); | 1513 | status = hid->driver->resume(hid); |
1507 | return status; | 1514 | return status; |
@@ -1570,12 +1577,8 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) | |||
1570 | static int hid_resume(struct usb_interface *intf) | 1577 | static int hid_resume(struct usb_interface *intf) |
1571 | { | 1578 | { |
1572 | struct hid_device *hid = usb_get_intfdata (intf); | 1579 | struct hid_device *hid = usb_get_intfdata (intf); |
1573 | struct usbhid_device *usbhid = hid->driver_data; | ||
1574 | int status; | 1580 | int status; |
1575 | 1581 | ||
1576 | if (!test_bit(HID_STARTED, &usbhid->iofl)) | ||
1577 | return 0; | ||
1578 | |||
1579 | status = hid_resume_common(hid, true); | 1582 | status = hid_resume_common(hid, true); |
1580 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1583 | dev_dbg(&intf->dev, "resume status %d\n", status); |
1581 | return 0; | 1584 | return 0; |
@@ -1584,10 +1587,8 @@ static int hid_resume(struct usb_interface *intf) | |||
1584 | static int hid_reset_resume(struct usb_interface *intf) | 1587 | static int hid_reset_resume(struct usb_interface *intf) |
1585 | { | 1588 | { |
1586 | struct hid_device *hid = usb_get_intfdata(intf); | 1589 | struct hid_device *hid = usb_get_intfdata(intf); |
1587 | struct usbhid_device *usbhid = hid->driver_data; | ||
1588 | int status; | 1590 | int status; |
1589 | 1591 | ||
1590 | clear_bit(HID_SUSPENDED, &usbhid->iofl); | ||
1591 | status = hid_post_reset(intf); | 1592 | status = hid_post_reset(intf); |
1592 | if (status >= 0 && hid->driver && hid->driver->reset_resume) { | 1593 | if (status >= 0 && hid->driver && hid->driver->reset_resume) { |
1593 | int ret = hid->driver->reset_resume(hid); | 1594 | int ret = hid->driver->reset_resume(hid); |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 68a560957871..ccf1883318c3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -152,6 +152,25 @@ static void wacom_feature_mapping(struct hid_device *hdev, | |||
152 | hid_data->inputmode = field->report->id; | 152 | hid_data->inputmode = field->report->id; |
153 | hid_data->inputmode_index = usage->usage_index; | 153 | hid_data->inputmode_index = usage->usage_index; |
154 | break; | 154 | break; |
155 | |||
156 | case HID_UP_DIGITIZER: | ||
157 | if (field->report->id == 0x0B && | ||
158 | (field->application == WACOM_G9_DIGITIZER || | ||
159 | field->application == WACOM_G11_DIGITIZER)) { | ||
160 | wacom->wacom_wac.mode_report = field->report->id; | ||
161 | wacom->wacom_wac.mode_value = 0; | ||
162 | } | ||
163 | break; | ||
164 | |||
165 | case WACOM_G9_PAGE: | ||
166 | case WACOM_G11_PAGE: | ||
167 | if (field->report->id == 0x03 && | ||
168 | (field->application == WACOM_G9_TOUCHSCREEN || | ||
169 | field->application == WACOM_G11_TOUCHSCREEN)) { | ||
170 | wacom->wacom_wac.mode_report = field->report->id; | ||
171 | wacom->wacom_wac.mode_value = 0; | ||
172 | } | ||
173 | break; | ||
155 | } | 174 | } |
156 | } | 175 | } |
157 | 176 | ||
@@ -322,26 +341,41 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev) | |||
322 | return 0; | 341 | return 0; |
323 | } | 342 | } |
324 | 343 | ||
325 | static int wacom_set_device_mode(struct hid_device *hdev, int report_id, | 344 | static int wacom_set_device_mode(struct hid_device *hdev, |
326 | int length, int mode) | 345 | struct wacom_wac *wacom_wac) |
327 | { | 346 | { |
328 | unsigned char *rep_data; | 347 | u8 *rep_data; |
348 | struct hid_report *r; | ||
349 | struct hid_report_enum *re; | ||
350 | int length; | ||
329 | int error = -ENOMEM, limit = 0; | 351 | int error = -ENOMEM, limit = 0; |
330 | 352 | ||
331 | rep_data = kzalloc(length, GFP_KERNEL); | 353 | if (wacom_wac->mode_report < 0) |
354 | return 0; | ||
355 | |||
356 | re = &(hdev->report_enum[HID_FEATURE_REPORT]); | ||
357 | r = re->report_id_hash[wacom_wac->mode_report]; | ||
358 | if (!r) | ||
359 | return -EINVAL; | ||
360 | |||
361 | rep_data = hid_alloc_report_buf(r, GFP_KERNEL); | ||
332 | if (!rep_data) | 362 | if (!rep_data) |
333 | return error; | 363 | return -ENOMEM; |
364 | |||
365 | length = hid_report_len(r); | ||
334 | 366 | ||
335 | do { | 367 | do { |
336 | rep_data[0] = report_id; | 368 | rep_data[0] = wacom_wac->mode_report; |
337 | rep_data[1] = mode; | 369 | rep_data[1] = wacom_wac->mode_value; |
338 | 370 | ||
339 | error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data, | 371 | error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data, |
340 | length, 1); | 372 | length, 1); |
341 | if (error >= 0) | 373 | if (error >= 0) |
342 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, | 374 | error = wacom_get_report(hdev, HID_FEATURE_REPORT, |
343 | rep_data, length, 1); | 375 | rep_data, length, 1); |
344 | } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES); | 376 | } while (error >= 0 && |
377 | rep_data[1] != wacom_wac->mode_report && | ||
378 | limit++ < WAC_MSG_RETRIES); | ||
345 | 379 | ||
346 | kfree(rep_data); | 380 | kfree(rep_data); |
347 | 381 | ||
@@ -411,32 +445,41 @@ static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed, | |||
411 | static int wacom_query_tablet_data(struct hid_device *hdev, | 445 | static int wacom_query_tablet_data(struct hid_device *hdev, |
412 | struct wacom_features *features) | 446 | struct wacom_features *features) |
413 | { | 447 | { |
448 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
449 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
450 | |||
414 | if (hdev->bus == BUS_BLUETOOTH) | 451 | if (hdev->bus == BUS_BLUETOOTH) |
415 | return wacom_bt_query_tablet_data(hdev, 1, features); | 452 | return wacom_bt_query_tablet_data(hdev, 1, features); |
416 | 453 | ||
417 | if (features->type == HID_GENERIC) | 454 | if (features->type != HID_GENERIC) { |
418 | return wacom_hid_set_device_mode(hdev); | 455 | if (features->device_type & WACOM_DEVICETYPE_TOUCH) { |
419 | 456 | if (features->type > TABLETPC) { | |
420 | if (features->device_type & WACOM_DEVICETYPE_TOUCH) { | 457 | /* MT Tablet PC touch */ |
421 | if (features->type > TABLETPC) { | 458 | wacom_wac->mode_report = 3; |
422 | /* MT Tablet PC touch */ | 459 | wacom_wac->mode_value = 4; |
423 | return wacom_set_device_mode(hdev, 3, 4, 4); | 460 | } else if (features->type == WACOM_24HDT) { |
424 | } | 461 | wacom_wac->mode_report = 18; |
425 | else if (features->type == WACOM_24HDT) { | 462 | wacom_wac->mode_value = 2; |
426 | return wacom_set_device_mode(hdev, 18, 3, 2); | 463 | } else if (features->type == WACOM_27QHDT) { |
427 | } | 464 | wacom_wac->mode_report = 131; |
428 | else if (features->type == WACOM_27QHDT) { | 465 | wacom_wac->mode_value = 2; |
429 | return wacom_set_device_mode(hdev, 131, 3, 2); | 466 | } else if (features->type == BAMBOO_PAD) { |
430 | } | 467 | wacom_wac->mode_report = 2; |
431 | else if (features->type == BAMBOO_PAD) { | 468 | wacom_wac->mode_value = 2; |
432 | return wacom_set_device_mode(hdev, 2, 2, 2); | 469 | } |
433 | } | 470 | } else if (features->device_type & WACOM_DEVICETYPE_PEN) { |
434 | } else if (features->device_type & WACOM_DEVICETYPE_PEN) { | 471 | if (features->type <= BAMBOO_PT) { |
435 | if (features->type <= BAMBOO_PT) { | 472 | wacom_wac->mode_report = 2; |
436 | return wacom_set_device_mode(hdev, 2, 2, 2); | 473 | wacom_wac->mode_value = 2; |
474 | } | ||
437 | } | 475 | } |
438 | } | 476 | } |
439 | 477 | ||
478 | wacom_set_device_mode(hdev, wacom_wac); | ||
479 | |||
480 | if (features->type == HID_GENERIC) | ||
481 | return wacom_hid_set_device_mode(hdev); | ||
482 | |||
440 | return 0; | 483 | return 0; |
441 | } | 484 | } |
442 | 485 | ||
@@ -1817,6 +1860,9 @@ static int wacom_probe(struct hid_device *hdev, | |||
1817 | goto fail_type; | 1860 | goto fail_type; |
1818 | } | 1861 | } |
1819 | 1862 | ||
1863 | wacom_wac->hid_data.inputmode = -1; | ||
1864 | wacom_wac->mode_report = -1; | ||
1865 | |||
1820 | wacom->usbdev = dev; | 1866 | wacom->usbdev = dev; |
1821 | wacom->intf = intf; | 1867 | wacom->intf = intf; |
1822 | mutex_init(&wacom->lock); | 1868 | mutex_init(&wacom->lock); |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bd198bbd4df0..02c4efea241c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -2426,6 +2426,17 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
2426 | } | 2426 | } |
2427 | 2427 | ||
2428 | /* | 2428 | /* |
2429 | * Hack for the Bamboo One: | ||
2430 | * the device presents a PAD/Touch interface as most Bamboos and even | ||
2431 | * sends ghosts PAD data on it. However, later, we must disable this | ||
2432 | * ghost interface, and we can not detect it unless we set it here | ||
2433 | * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH. | ||
2434 | */ | ||
2435 | if (features->type == BAMBOO_PEN && | ||
2436 | features->pktlen == WACOM_PKGLEN_BBTOUCH3) | ||
2437 | features->device_type |= WACOM_DEVICETYPE_PAD; | ||
2438 | |||
2439 | /* | ||
2429 | * Raw Wacom-mode pen and touch events both come from interface | 2440 | * Raw Wacom-mode pen and touch events both come from interface |
2430 | * 0, whose HID descriptor has an application usage of 0xFF0D | 2441 | * 0, whose HID descriptor has an application usage of 0xFF0D |
2431 | * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back | 2442 | * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 25baa7f29599..e2084d914c14 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -84,6 +84,12 @@ | |||
84 | #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 | 84 | #define WACOM_DEVICETYPE_WL_MONITOR 0x0008 |
85 | 85 | ||
86 | #define WACOM_VENDORDEFINED_PEN 0xff0d0001 | 86 | #define WACOM_VENDORDEFINED_PEN 0xff0d0001 |
87 | #define WACOM_G9_PAGE 0xff090000 | ||
88 | #define WACOM_G9_DIGITIZER (WACOM_G9_PAGE | 0x02) | ||
89 | #define WACOM_G9_TOUCHSCREEN (WACOM_G9_PAGE | 0x11) | ||
90 | #define WACOM_G11_PAGE 0xff110000 | ||
91 | #define WACOM_G11_DIGITIZER (WACOM_G11_PAGE | 0x02) | ||
92 | #define WACOM_G11_TOUCHSCREEN (WACOM_G11_PAGE | 0x11) | ||
87 | 93 | ||
88 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ | 94 | #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \ |
89 | ((f)->physical == HID_DG_STYLUS) || \ | 95 | ((f)->physical == HID_DG_STYLUS) || \ |
@@ -238,6 +244,8 @@ struct wacom_wac { | |||
238 | int ps_connected; | 244 | int ps_connected; |
239 | u8 bt_features; | 245 | u8 bt_features; |
240 | u8 bt_high_speed; | 246 | u8 bt_high_speed; |
247 | int mode_report; | ||
248 | int mode_value; | ||
241 | struct hid_data hid_data; | 249 | struct hid_data hid_data; |
242 | }; | 250 | }; |
243 | 251 | ||