diff options
| -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 | ||
