]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branches 'for-3.19/hid-report-len', 'for-3.19/i2c-hid', 'for-3.19/lenovo',...
authorJiri Kosina <jkosina@suse.cz>
Fri, 12 Dec 2014 10:15:33 +0000 (11:15 +0100)
committerJiri Kosina <jkosina@suse.cz>
Fri, 12 Dec 2014 10:15:33 +0000 (11:15 +0100)
1  2  3  4  5  6  7  8  9  10 
drivers/hid/Kconfig
drivers/hid/Makefile
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c
include/linux/hid.h

diff --combined drivers/hid/Kconfig
index 3a3f29c0cc360e848a9c655bc6b9c17c9c7b0ae0,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,dd49a9b14b9cd49d8aef43d28d7161910fa014f0,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,bf1c74e19c75ae36bd64e21de45e452203490103,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9,f42df4dd58d285dff4eac05ba9ff7e8688bf4de9..230b6f887cd86e9b4d3d4bf625166c878d5524ed
@@@@@@@@@@@ -371,6 -371,6 -371,6 -371,6 -371,7 -371,6 -371,6 -371,6 -371,6 -371,6 +371,7 @@@@@@@@@@@ config HID_LOGITECH_D
                tristate "Logitech Unifying receivers full support"
                depends on HIDRAW
                depends on HID_LOGITECH
++++ +++++      select HID_LOGITECH_HIDPP
                ---help---
                Say Y if you want support for Logitech Unifying receivers and devices.
                Unifying receivers are capable of pairing up to 6 Logitech compliant
                generic USB_HID driver and all incoming events will be multiplexed
                into a single mouse and a single keyboard device.
          
++++ +++++config HID_LOGITECH_HIDPP
++++ +++++      tristate "Logitech HID++ devices support"
++++ +++++      depends on HID_LOGITECH
++++ +++++      ---help---
++++ +++++      Support for Logitech devices relyingon the HID++ Logitech specification
++++ +++++
++++ +++++      Say Y if you want support for Logitech devices relying on the HID++
++++ +++++      specification. Such devices are the various Logitech Touchpads (T650,
++++ +++++      T651, TK820), some mice (Zone Touch mouse), or even keyboards (Solar
++++ +++++      Keayboard).
++++ +++++
          config LOGITECH_FF
                bool "Logitech force feedback support"
                depends on HID_LOGITECH
@@@@@@@@@@@ -613,6 -613,6 -613,6 -613,6 -625,6 -613,6 -613,13 -613,6 -613,6 -613,6 +625,13 @@@@@@@@@@@ config HID_PICOLCD_CI
                ---help---
                  Provide access to PicoLCD's CIR interface via remote control (LIRC).
          
++++++ +++config HID_PLANTRONICS
++++++ +++      tristate "Plantronics USB HID Driver"
++++++ +++      default !EXPERT
++++++ +++      depends on HID
++++++ +++      ---help---
++++++ +++      Provides HID support for Plantronics telephony devices.
++++++ +++
          config HID_PRIMAX
                tristate "Primax non-fully HID-compliant devices"
                depends on HID
@@@@@@@@@@@ -629,7 -629,7 -629,7 -629,7 -641,7 -629,7 -636,7 -629,7 -629,7 -629,7 +648,7 @@@@@@@@@@@ config HID_ROCCA
                support for its special functionalities.
          
          config HID_SAITEK
 ---------      tristate "Saitek non-fully HID-compliant devices"
 +++++++++      tristate "Saitek (Mad Catz) non-fully HID-compliant devices"
                depends on HID
                ---help---
                Support for Saitek devices that are not fully compliant with the
          
                Supported devices:
                - PS1000 Dual Analog Pad
 +++++++++      - R.A.T.9 Gaming Mouse
                - R.A.T.7 Gaming Mouse
                - M.M.O.7 Gaming Mouse
          
diff --combined drivers/hid/Makefile
index e2850d8af9ca353a3b95ad6706667266f5a804b8,e2850d8af9ca353a3b95ad6706667266f5a804b8,e2850d8af9ca353a3b95ad6706667266f5a804b8,e2850d8af9ca353a3b95ad6706667266f5a804b8,b102774b4e16cdc8e1ad6c6c96654c5c88649288,e2850d8af9ca353a3b95ad6706667266f5a804b8,5e7ac59447d860ddc747fc74df3d97dacfaf954b,e2850d8af9ca353a3b95ad6706667266f5a804b8,e2850d8af9ca353a3b95ad6706667266f5a804b8,e2850d8af9ca353a3b95ad6706667266f5a804b8..debd15b44b591b12ad363a1cb50b21421889114c
@@@@@@@@@@@ -63,6 -63,6 -63,6 -63,6 -63,7 -63,6 -63,6 -63,6 -63,6 -63,6 +63,7 @@@@@@@@@@@ obj-$(CONFIG_HID_LCPOWER)       += hid-
          obj-$(CONFIG_HID_LENOVO)      += hid-lenovo.o
          obj-$(CONFIG_HID_LOGITECH)    += hid-logitech.o
          obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
++++ +++++obj-$(CONFIG_HID_LOGITECH_HIDPP)      += hid-logitech-hidpp.o
          obj-$(CONFIG_HID_MAGICMOUSE)    += hid-magicmouse.o
          obj-$(CONFIG_HID_MICROSOFT)   += hid-microsoft.o
          obj-$(CONFIG_HID_MONTEREY)    += hid-monterey.o
@@@@@@@@@@@ -94,6 -94,6 -94,6 -94,6 -95,6 -94,6 -94,7 -94,6 -94,6 -94,6 +95,7 @@@@@@@@@@@ ifdef CONFIG_DEBUG_F
          hid-picolcd-y                 += hid-picolcd_debugfs.o
          endif
          
++++++ +++obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
          obj-$(CONFIG_HID_PRIMAX)      += hid-primax.o
          obj-$(CONFIG_HID_ROCCAT)      += hid-roccat.o hid-roccat-common.o \
                hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
diff --combined drivers/hid/hid-core.c
index bae74afa5e0045038dcf99e1b5d48544acbe1d60,ee6ba7625e776d804f7ef1d5bb1d5be36a21f4f0,3402033fa52a7225c0a91846eba5237af8d08142,73bd9e2e42bc3c7dfbd249c0a1d3d4e1c78a19f9,395549fea44ccfe718aa3fce16294e3521c961ef,e94afcc19edaa3fbc5bcfd6dab0e88b285290ad5,d50313ca64a61c1f9e2e314961ebd02db9c02465,3402033fa52a7225c0a91846eba5237af8d08142,0ab6d6af54c8bc84f73cd032decee31915d75e18,73bd9e2e42bc3c7dfbd249c0a1d3d4e1c78a19f9..c3d0ac1a0988096eaacbe8063b354399b6a85e14
@@@@@@@@@@@ -702,6 -702,6 -702,6 -702,6 -702,6 -702,11 -702,6 -702,6 -702,6 -702,6 +702,11 @@@@@@@@@@@ static void hid_scan_collection(struct 
                if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
                    type == HID_COLLECTION_PHYSICAL)
                        hid->group = HID_GROUP_SENSOR_HUB;
+++++ ++++
+++++ ++++      if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
+++++ ++++          hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 &&
+++++ ++++          hid->group == HID_GROUP_MULTITOUCH)
+++++ ++++              hid->group = HID_GROUP_GENERIC;
          }
          
          static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
@@@@@@@@@@@ -779,6 -779,16 -779,16 -779,16 -779,6 -784,16 -779,16 -779,16 -779,16 -779,16 +784,6 @@@@@@@@@@@ static int hid_scan_report(struct hid_d
                    (hid->group == HID_GROUP_MULTITOUCH))
                        hid->group = HID_GROUP_MULTITOUCH_WIN_8;
          
 --- -----      /*
 --- -----      * Vendor specific handlings
 --- -----      */
 --- -----      if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) &&
 --- -----          (hid->group == HID_GROUP_GENERIC) &&
 --- -----          /* only bind to the mouse interface of composite USB devices */
 --- -----          (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
 --- -----              /* hid-rmi should take care of them, not hid-generic */
 --- -----              hid->group = HID_GROUP_RMI;
 --- -----
                /*
                 * Vendor specific handlings
                 */
                case USB_VENDOR_ID_WACOM:
                        hid->group = HID_GROUP_WACOM;
                        break;
 +++ +++++      case USB_VENDOR_ID_SYNAPTICS:
 +++ +++++              if ((hid->group == HID_GROUP_GENERIC) &&
 +++ +++++                  (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
 +++ +++++                      /* hid-rmi should only bind to the mouse interface of
 +++ +++++                       * composite USB devices */
 +++ +++++                      hid->group = HID_GROUP_RMI;
 +++ +++++              break;
                }
          
                vfree(parser);
@@@@@@@@@@@ -1277,12 -1280,6 -1280,12 -1280,12 -1277,12 -1285,12 -1280,12 -1280,12 -1280,12 -1280,12 +1282,6 @@@@@@@@@@@ void hid_output_report(struct hid_repor
          }
          EXPORT_SYMBOL_GPL(hid_output_report);
          
- --------static int hid_report_len(struct hid_report *report)
- --------{
- --------      /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
- --------      return ((report->size - 1) >> 3) + 1 + (report->id > 0);
- --------}
- --------
          /*
           * Allocator for buffer that is going to be passed to hid_output_report()
           */
@@@@@@@@@@@ -1656,7 -1653,7 -1659,7 -1659,6 -1656,6 -1664,6 -1659,6 -1659,7 -1659,7 -1659,6 +1655,7 @@@@@@@@@@@ void hid_disconnect(struct hid_device *
                        hdev->hiddev_disconnect(hdev);
                if (hdev->claimed & HID_CLAIMED_HIDRAW)
                        hidraw_disconnect(hdev);
   ++++  +      hdev->claimed = 0;
          }
          EXPORT_SYMBOL_GPL(hid_disconnect);
          
@@@@@@@@@@@ -1819,6 -1816,6 -1822,6 -1821,6 -1818,7 -1826,6 -1821,6 -1822,6 -1822,6 -1821,6 +1818,7 @@@@@@@@@@@ static const struct hid_device_id hid_h
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
++++ +++++      { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
+++++ ++++      { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
                { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
                { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
                { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
++++++ +++      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
                { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
          #if IS_ENABLED(CONFIG_HID_ROCCAT)
                { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
 +++++++++      { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
          #endif
                { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
++++++++ +      { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
                { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
@@@@@@@@@@@ -2537,8 -2533,7 -2539,7 -2538,7 -2536,8 -2544,7 -2539,7 -2539,7 -2540,7 -2538,7 +2540,8 @@@@@@@@@@@ int hid_add_device(struct hid_device *h
                 * Scan generic devices for group information
                 */
                if (hid_ignore_special_drivers ||
 --- -----          !hid_match_id(hdev, hid_have_special_driver)) {
 +++ +++++          (!hdev->group &&
 +++ +++++           !hid_match_id(hdev, hid_have_special_driver))) {
                        ret = hid_scan_report(hdev);
                        if (ret)
                                hid_warn(hdev, "bad device descriptor (%d)\n", ret);
diff --combined drivers/hid/hid-ids.h
index 40627c713519e97dbcad630915342b8d6e7b7f5c,d6cc6a9cf10fa9be3ac01e8906c7fe8a7e0d48a7,7c863738e419969a9dd0115ca7321d884034ae59,e23ab8b30626dae386ebc84e507c55a8e5dcea6c,2aa5091ecc08b1ed8ceeb793370f527fc73ea135,0d38df761e29c604f1f9285afc8eb439b3439958,f9f476db671cf9ec1e76f80b29a32fcfd9cdef32,7c863738e419969a9dd0115ca7321d884034ae59,27e0f5188d081ffc7195be9c26ee015b186f2587,e23ab8b30626dae386ebc84e507c55a8e5dcea6c..7460f3402298c2e1925059a1ef5cbf669e9d381b
          
          #define USB_VENDOR_ID_ELAN            0x04f3
          #define USB_DEVICE_ID_ELAN_TOUCHSCREEN        0x0089
    ++    #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B   0x009b
   ++++  +#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103   0x0103
 +++++++++#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c   0x010c
    ++    #define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F   0x016f
          
          #define USB_VENDOR_ID_ELECOM          0x056e
          #define USB_DEVICE_ID_ELECOM_BM084    0x0061
          
          #define USB_VENDOR_ID_LOGITECH                0x046d
          #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
++++ +++++#define USB_DEVICE_ID_LOGITECH_T651   0xb00c
          #define USB_DEVICE_ID_LOGITECH_RECEIVER       0xc101
          #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
          #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
          
          #define USB_VENDOR_ID_MADCATZ         0x0738
          #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540
 +++++++++#define USB_DEVICE_ID_MADCATZ_RAT9    0x1709
          
          #define USB_VENDOR_ID_MCC             0x09db
          #define USB_DEVICE_ID_MCC_PMD1024LS   0x0076
          #define USB_DEVICE_ID_MS_SURFACE_PRO_2   0x0799
          #define USB_DEVICE_ID_MS_TOUCH_COVER_2   0x07a7
          #define USB_DEVICE_ID_MS_TYPE_COVER_2    0x07a9
+++++ ++++#define USB_DEVICE_ID_MS_TYPE_COVER_3    0x07dc
          
          #define USB_VENDOR_ID_MOJO            0x8282
          #define USB_DEVICE_ID_RETRO_ADAPTER   0x3201
          #define USB_DEVICE_ID_ORTEK_PKB1700   0x1700
          #define USB_DEVICE_ID_ORTEK_WKB2000   0x2000
          
++++++ +++#define USB_VENDOR_ID_PLANTRONICS     0x047f
++++++ +++
          #define USB_VENDOR_ID_PANASONIC               0x04da
          #define USB_DEVICE_ID_PANABOARD_UBT780        0x1044
          #define USB_DEVICE_ID_PANABOARD_UBT880        0x104d
          #define USB_VENDOR_ID_SKYCABLE                        0x1223
          #define       USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER       0x3F07
          
++++++++ +#define USB_VENDOR_ID_SMK             0x0609
++++++++ +#define USB_DEVICE_ID_SMK_PS3_BDREMOTE        0x0306
++++++++ +
          #define USB_VENDOR_ID_SONY                    0x054c
          #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE     0x024b
          #define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE     0x0374
          #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
          #define USB_DEVICE_ID_VERNIER_LCSPEC  0x0006
          
+ ++++++++#define USB_VENDOR_ID_VTL             0x0306
+ ++++++++#define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F     0xff3f
+ ++++++++
          #define USB_VENDOR_ID_WACOM           0x056a
          #define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH        0x81
          #define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH   0x00BD
diff --combined drivers/hid/hid-input.c
index be3eba8b973117347224acf86c43e5d093ef8a7d,1e95f4df414618420c5745a99b85ef9afb502e44,725f22ca47fcb808401dc08120ad0366bb9d9d69,725f22ca47fcb808401dc08120ad0366bb9d9d69,7ea582be9c9aeac1dd67716bfa325c37d3aef00f,2df7fddbd119bc0cccb5f9cc2a6c4a01bbc9f7e8,725f22ca47fcb808401dc08120ad0366bb9d9d69,725f22ca47fcb808401dc08120ad0366bb9d9d69,725f22ca47fcb808401dc08120ad0366bb9d9d69,725f22ca47fcb808401dc08120ad0366bb9d9d69..e0a0f06ac5ef6168c8fcdd5c2462df3f3130c941
@@@@@@@@@@@ -695,10 -695,10 -695,10 -695,10 -695,7 -695,7 -695,10 -695,10 -695,10 -695,10 +695,10 @@@@@@@@@@@ static void hidinput_configure_usage(st
                                break;
          
                        case 0x5b: /* TransducerSerialNumber */
    --                          set_bit(MSC_SERIAL, input->mscbit);
    ++                          usage->type = EV_MSC;
    ++                          usage->code = MSC_SERIAL;
    ++                          bit = input->mscbit;
    ++                          max = MSC_MAX;
                                break;
          
                        default:  goto unknown;
                        case 0x28b: map_key_clear(KEY_FORWARDMAIL);     break;
                        case 0x28c: map_key_clear(KEY_SEND);            break;
          
     -                  default:    goto ignore;
    ++                  case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV);             break;
    ++                  case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT);             break;
    ++                  case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP);                break;
    ++                  case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP);                break;
    ++                  case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT);   break;
    ++                  case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL);   break;
    ++    
 ---  ----              default:    goto ignore;
 +++ +++++              default: map_key_clear(KEY_UNKNOWN);
                        }
                        break;
          
@@@@@@@@@@@ -1215,7 -1215,7 -1215,7 -1215,7 -1205,7 -1205,7 -1215,7 -1215,7 -1215,7 -1215,7 +1215,7 @@@@@@@@@@@ static void hidinput_led_worker(struct 
                        return hid->ll_driver->request(hid, report, HID_REQ_SET_REPORT);
          
                /* fall back to generic raw-output-report */
- --------      len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ ++++++++      len = hid_report_len(report);
                buf = hid_alloc_report_buf(report, GFP_KERNEL);
                if (!buf)
                        return;
index 9c014803b460c92c468d446d98c5aea12b1a2977,747d54421e733a407949f50762bb62c5e596fb34,c66e6acf715256b65b1cd547342092e2b679909c,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34,747d54421e733a407949f50762bb62c5e596fb34..fbd07812f2d9673c7dc8a883eaadccb95244b2b0
@@@@@@@@@@@ -137,6 -137,6 -137,7 -137,6 -137,6 -137,6 -137,6 -137,6 -137,6 -137,6 +137,7 @@@@@@@@@@@ struct i2c_hid 
                                                           * descriptor. */
                unsigned int            bufsize;        /* i2c buffer size */
                char                    *inbuf;         /* Input buffer */
++ +++++++      char                    *rawbuf;        /* Raw Input buffer */
                char                    *cmdbuf;        /* Command buffer */
                char                    *argsbuf;       /* Command arguments buffer */
          
@@@@@@@@@@@ -369,7 -369,7 -370,7 -369,7 -369,7 -369,7 -369,7 -369,7 -369,7 -369,7 +370,7 @@@@@@@@@@@ static int i2c_hid_hwreset(struct i2c_c
          static void i2c_hid_get_input(struct i2c_hid *ihid)
          {
                int ret, ret_size;
 ---------      int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
 +++++++++      int size = ihid->bufsize;
          
                ret = i2c_master_recv(ihid->client, ihid->inbuf, size);
                if (ret != size) {
@@@@@@@@@@@ -437,7 -437,7 -438,7 -437,7 -437,7 -437,7 -437,7 -437,7 -437,7 -437,7 +438,7 @@@@@@@@@@@ static void i2c_hid_init_report(struct 
                                report->id, buffer, size))
                        return;
          
-- -------      i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf);
++ +++++++      i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, buffer);
          
                ret_size = buffer[0] | (buffer[1] << 8);
          
@@@@@@@@@@@ -504,9 -504,9 -505,11 -504,9 -504,9 -504,9 -504,9 -504,9 -504,9 -504,9 +505,11 @@@@@@@@@@@ static void i2c_hid_find_max_report(str
          static void i2c_hid_free_buffers(struct i2c_hid *ihid)
          {
                kfree(ihid->inbuf);
++ +++++++      kfree(ihid->rawbuf);
                kfree(ihid->argsbuf);
                kfree(ihid->cmdbuf);
                ihid->inbuf = NULL;
++ +++++++      ihid->rawbuf = NULL;
                ihid->cmdbuf = NULL;
                ihid->argsbuf = NULL;
                ihid->bufsize = 0;
@@@@@@@@@@@ -522,10 -522,10 -525,11 -522,10 -522,10 -522,10 -522,10 -522,10 -522,10 -522,10 +525,11 @@@@@@@@@@@ static int i2c_hid_alloc_buffers(struc
                               report_size; /* report */
          
                ihid->inbuf = kzalloc(report_size, GFP_KERNEL);
++ +++++++      ihid->rawbuf = kzalloc(report_size, GFP_KERNEL);
                ihid->argsbuf = kzalloc(args_len, GFP_KERNEL);
                ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL);
          
-- -------      if (!ihid->inbuf || !ihid->argsbuf || !ihid->cmdbuf) {
++ +++++++      if (!ihid->inbuf || !ihid->rawbuf || !ihid->argsbuf || !ihid->cmdbuf) {
                        i2c_hid_free_buffers(ihid);
                        return -ENOMEM;
                }
@@@@@@@@@@@ -552,12 -552,12 -556,12 -552,12 -552,12 -552,12 -552,12 -552,12 -552,12 -552,12 +556,12 @@@@@@@@@@@ static int i2c_hid_get_raw_report(struc
          
                ret = i2c_hid_get_report(client,
                                report_type == HID_FEATURE_REPORT ? 0x03 : 0x01,
-- -------                      report_number, ihid->inbuf, ask_count);
++ +++++++                      report_number, ihid->rawbuf, ask_count);
          
                if (ret < 0)
                        return ret;
          
-- -------      ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8);
++ +++++++      ret_count = ihid->rawbuf[0] | (ihid->rawbuf[1] << 8);
          
                if (ret_count <= 2)
                        return 0;
          
                /* The query buffer contains the size, dropping it in the reply */
                count = min(count, ret_count - 2);
-- -------      memcpy(buf, ihid->inbuf + 2, count);
++ +++++++      memcpy(buf, ihid->rawbuf + 2, count);
          
                return count;
          }
index 04e34b917045a76e6f5d91b801d86218e00ecf3c,b6cb7a5e4b2700d38542e687656c04e53ac8684e,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8,ca6849a0121e7bee62b23740f52c0a66bddde5e8..bfbe1bedda7f34396db34e85b79c89ee1a251209
@@@@@@@@@@@ -278,20 -278,18 -278,18 -278,18 -278,18 -278,18 -278,18 -278,18 -278,18 -278,18 +278,20 @@@@@@@@@@@ static void hid_irq_in(struct urb *urb
                        usbhid->retry_delay = 0;
                        if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open)
                                break;
 ---------              hid_input_report(urb->context, HID_INPUT_REPORT,
 ---------                               urb->transfer_buffer,
 ---------                               urb->actual_length, 1);
 ---------              /*
 ---------               * autosuspend refused while keys are pressed
 ---------               * because most keyboards don't wake up when
 ---------               * a key is released
 ---------               */
 ---------              if (hid_check_keys_pressed(hid))
 ---------                      set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 ---------              else
 ---------                      clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 +++++++++              if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
 +++++++++                      hid_input_report(urb->context, HID_INPUT_REPORT,
 +++++++++                                       urb->transfer_buffer,
 +++++++++                                       urb->actual_length, 1);
 +++++++++                      /*
 +++++++++                       * autosuspend refused while keys are pressed
 +++++++++                       * because most keyboards don't wake up when
 +++++++++                       * a key is released
 +++++++++                       */
 +++++++++                      if (hid_check_keys_pressed(hid))
 +++++++++                              set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 +++++++++                      else
 +++++++++                              clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 +++++++++              }
                        break;
                case -EPIPE:            /* stall */
                        usbhid_mark_busy(usbhid);
@@@@@@@@@@@ -340,8 -338,7 -338,8 -338,8 -338,8 -338,8 -338,8 -338,8 -338,8 -338,8 +340,7 @@@@@@@@@@@ static int hid_submit_out(struct hid_de
                report = usbhid->out[usbhid->outtail].report;
                raw_report = usbhid->out[usbhid->outtail].raw_report;
          
- --------      usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) +
- --------                                               1 + (report->id > 0);
+ ++++++++      usbhid->urbout->transfer_buffer_length = hid_report_len(report);
                usbhid->urbout->dev = hid_to_usb_dev(hid);
                if (raw_report) {
                        memcpy(usbhid->outbuf, raw_report,
@@@@@@@@@@@ -690,7 -687,6 -688,6 -688,6 -688,6 -688,6 -688,6 -688,6 -688,6 -688,6 +689,7 @@@@@@@@@@@ int usbhid_open(struct hid_device *hid
                                goto done;
                        }
                        usbhid->intf->needs_remote_wakeup = 1;
 +++++++++              set_bit(HID_RESUME_RUNNING, &usbhid->iofl);
                        res = hid_start_in(hid);
                        if (res) {
                                if (res != -ENOSPC) {
                                }
                        }
                        usb_autopm_put_interface(usbhid->intf);
 +++++++++
 +++++++++              /*
 +++++++++               * In case events are generated while nobody was listening,
 +++++++++               * some are released when the device is re-opened.
 +++++++++               * Wait 50 msec for the queue to empty before allowing events
 +++++++++               * to go through hid.
 +++++++++               */
 +++++++++              msleep(50);
 +++++++++              clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
                }
          done:
                mutex_unlock(&hid_open_mut);
index 3e5f169d35f3418c5c50eb50dd643ef1ac6aa947,552671ee7c5d7c6344fb92bca48f4f2d601b640e,552671ee7c5d7c6344fb92bca48f4f2d601b640e,5014bb567b29cd8f2799873ffb869ac55a28c6ae,f3cb5b0a43454e7b27b2d8c0e3ddf817aa539e6f,be6763524fe8bb4828570273bf2264e19bcb1397,5014bb567b29cd8f2799873ffb869ac55a28c6ae,552671ee7c5d7c6344fb92bca48f4f2d601b640e,552671ee7c5d7c6344fb92bca48f4f2d601b640e,5014bb567b29cd8f2799873ffb869ac55a28c6ae..dc89be90b35e80f7d14d5dcaa71dda082c8ab84b
@@@@@@@@@@@ -71,14 -71,13 -71,13 -71,12 -71,10 -71,11 -71,12 -71,13 -71,13 -71,12 +71,15 @@@@@@@@@@@ static const struct hid_blacklist 
                { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
    ++          { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
   ++++  +      { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL },
 +++++++++      { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_010c, HID_QUIRK_ALWAYS_POLL },
    ++          { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
                { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+++++ ++++      { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
diff --combined drivers/hid/wacom_sys.c
index b6bcd251c4a85f501f447a5ca6d9e2e4d2097605,8e02a4a6fde0c1f35547c3c1a2f73893dc83a063,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,8593047bb726cb1046ebbdba7a48a5802d1dc764,872aa0be2e70595ad3ec5aed970371bddd567ca0..654202941d307bc5216e2772b609b15a30e4f5a3
          
          #include "wacom_wac.h"
          #include "wacom.h"
+++++++++ #include <linux/input/mt.h>
          
          #define WAC_MSG_RETRIES               5
          
@@@@@@@@@@@ -70,15 -70,22 -70,22 -70,22 -70,22 -70,22 -70,22 -70,22 -70,22 -71,22 +71,15 @@@@@@@@@@@ static int wacom_raw_event(struct hid_d
          static int wacom_open(struct input_dev *dev)
          {
                struct wacom *wacom = input_get_drvdata(dev);
 ---------      int retval;
 -------- 
 --------       mutex_lock(&wacom->lock);
 --------       retval = hid_hw_open(wacom->hdev);
 --------       mutex_unlock(&wacom->lock);
          
         -      mutex_lock(&wacom->lock);
         -      retval = hid_hw_open(wacom->hdev);
         -      mutex_unlock(&wacom->lock);
         -
 ---------      return retval;
 +++++++++      return hid_hw_open(wacom->hdev);
          }
          
          static void wacom_close(struct input_dev *dev)
          {
                struct wacom *wacom = input_get_drvdata(dev);
          
 ---------      mutex_lock(&wacom->lock);
                hid_hw_close(wacom->hdev);
 ---------      mutex_unlock(&wacom->lock);
          }
          
          /*
@@@@@@@@@@@ -185,9 -192,9 -192,9 -192,9 -192,9 -192,9 -192,9 -192,9 -192,9 -193,15 +186,15 @@@@@@@@@@@ static void wacom_usage_mapping(struct 
                if (!pen && !finger)
                        return;
          
---------       if (finger && !features->touch_max)
---------               /* touch device at least supports one touch point */
---------               features->touch_max = 1;
+++++++++       /*
+++++++++        * Bamboo models do not support HID_DG_CONTACTMAX.
+++++++++        * And, Bamboo Pen only descriptor contains touch.
+++++++++        */
+++++++++       if (features->type != BAMBOO_PT) {
+++++++++               /* ISDv4 touch devices at least supports one touch point */
+++++++++               if (finger && !features->touch_max)
+++++++++                       features->touch_max = 1;
+++++++++       }
          
                switch (usage->hid) {
                case HID_GD_X:
                        wacom_wac_usage_mapping(hdev, field, usage);
          }
          
+++++++++ static void wacom_post_parse_hid(struct hid_device *hdev,
+++++++++                                struct wacom_features *features)
+++++++++ {
+++++++++       struct wacom *wacom = hid_get_drvdata(hdev);
+++++++++       struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+++++++++ 
+++++++++       if (features->type == HID_GENERIC) {
+++++++++               /* Any last-minute generic device setup */
+++++++++               if (features->touch_max > 1) {
+++++++++                       input_mt_init_slots(wacom_wac->input, wacom_wac->features.touch_max,
+++++++++                                   INPUT_MT_DIRECT);
+++++++++               }
+++++++++       }
+++++++++ }
+++++++++ 
          static void wacom_parse_hid(struct hid_device *hdev,
                                   struct wacom_features *features)
          {
                                        wacom_usage_mapping(hdev, hreport->field[i],
                                                        hreport->field[i]->usage + j);
                }
+++++++++ 
+++++++++       wacom_post_parse_hid(hdev, features);
          }
          
          static int wacom_hid_set_device_mode(struct hid_device *hdev)
@@@@@@@@@@@ -1122,7 -1129,7 -1129,7 -1129,7 -1129,7 -1129,7 -1129,7 -1129,7 -1129,7 -1153,7 +1146,7 @@@@@@@@@@@ static void wacom_clean_inputs(struct w
                                input_free_device(wacom->wacom_wac.input);
                }
                if (wacom->wacom_wac.pad_input) {
---------               if (wacom->wacom_wac.input_registered)
+++++++++               if (wacom->wacom_wac.pad_registered)
                                input_unregister_device(wacom->wacom_wac.pad_input);
                        else
                                input_free_device(wacom->wacom_wac.pad_input);
@@@@@@@@@@@ -1144,13 -1151,13 -1151,13 -1151,13 -1151,13 -1151,13 -1151,13 -1151,13 -1151,13 -1175,13 +1168,13 @@@@@@@@@@@ static int wacom_register_inputs(struc
                if (!input_dev || !pad_input_dev)
                        return -EINVAL;
          
---------       error = wacom_setup_input_capabilities(input_dev, wacom_wac);
---------       if (error)
---------               return error;
--------- 
---------       error = input_register_device(input_dev);
---------       if (error)
---------               return error;
+++++++++       error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac);
+++++++++       if (!error) {
+++++++++               error = input_register_device(input_dev);
+++++++++               if (error)
+++++++++                       return error;
+++++++++               wacom_wac->input_registered = true;
+++++++++       }
          
                error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
                if (error) {
                        error = input_register_device(pad_input_dev);
                        if (error)
                                goto fail_register_pad_input;
+++++++++               wacom_wac->pad_registered = true;
          
                        error = wacom_initialize_leds(wacom);
                        if (error)
                                goto fail_leds;
                }
          
---------       wacom_wac->input_registered = true;
--------- 
                return 0;
          
          fail_leds:
                input_unregister_device(pad_input_dev);
                pad_input_dev = NULL;
+++++++++       wacom_wac->pad_registered = false;
          fail_register_pad_input:
                input_unregister_device(input_dev);
                wacom_wac->input = NULL;
+++++++++       wacom_wac->input_registered = false;
                return error;
          }
          
@@@@@@@@@@@ -1314,12 -1321,6 -1321,12 -1321,12 -1321,12 -1321,12 -1321,12 -1321,12 -1321,12 -1346,12 +1339,6 @@@@@@@@@@@ static void wacom_calculate_res(struct 
                                                            features->unitExpo);
          }
          
- --------static int wacom_hid_report_len(struct hid_report *report)
- --------{
- --------      /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
- --------      return ((report->size - 1) >> 3) + 1 + (report->id > 0);
- --------}
- --------
          static size_t wacom_compute_pktlen(struct hid_device *hdev)
          {
                struct hid_report_enum *report_enum;
                report_enum = hdev->report_enum + HID_INPUT_REPORT;
          
                list_for_each_entry(report, &report_enum->report_list, list) {
- --------              size_t report_size = wacom_hid_report_len(report);
+ ++++++++              size_t report_size = hid_report_len(report);
                        if (report_size > size)
                                size = report_size;
                }
diff --combined drivers/hid/wacom_wac.c
index 7cf998cdd011c7898523ae7c04c96d714c0b1c08,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,586b2405b0d43836fc2653af5b39904c03802097,26f27bd6b95c7e6f818b99eaef403d248b764bf1..ac7447c7b82e35ff81209c31dd417fb8a53de112
          #define WACOM_INTUOS_RES      100
          #define WACOM_INTUOS3_RES     200
          
+++++++++ /* Newer Cintiq and DTU have an offset between tablet and screen areas */
+++++++++ #define WACOM_DTU_OFFSET      200
+++++++++ #define WACOM_CINTIQ_OFFSET   400
+++++++++ 
          /*
           * Scale factor relating reported contact size to logical contact area.
           * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo
@@@@@@@@@@@ -600,8 -600,8 -600,8 -600,8 -600,8 -600,8 -600,8 -600,8 -600,8 -604,8 +604,8 @@@@@@@@@@@ static void wacom_intuos_general(struc
                        }
                        input_report_abs(input, ABS_PRESSURE, t);
                        input_report_abs(input, ABS_TILT_X,
---------                               ((data[7] << 1) & 0x7e) | (data[8] >> 7));
---------               input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
+++++++++                                (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
+++++++++               input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
                        input_report_key(input, BTN_STYLUS, data[1] & 2);
                        input_report_key(input, BTN_STYLUS2, data[1] & 4);
                        input_report_key(input, BTN_TOUCH, t > 10);
                        input_report_abs(input, ABS_WHEEL,
                                        (data[6] << 2) | ((data[7] >> 6) & 3));
                        input_report_abs(input, ABS_TILT_X,
---------                               ((data[7] << 1) & 0x7e) | (data[8] >> 7));
---------               input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
+++++++++                                (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
+++++++++               input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
                }
          }
          
@@@@@@@@@@@ -915,8 -915,8 -915,8 -915,8 -915,8 -915,8 -915,8 -915,8 -915,8 -919,8 +919,8 @@@@@@@@@@@ static int wacom_intuos_irq(struct waco
                                        input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
          
                                        input_report_abs(input, ABS_TILT_X,
---------                                       ((data[7] << 1) & 0x7e) | (data[8] >> 7));
---------                               input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
+++++++++                                       (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
+++++++++                               input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
                                } else {
                                        /* 2D mouse packet */
                                        input_report_key(input, BTN_LEFT,   data[8] & 0x04);
@@@@@@@@@@@ -1377,11 -1377,11 -1377,11 -1377,11 -1377,11 -1377,11 -1377,11 -1377,11 -1377,11 -1381,12 +1381,12 @@@@@@@@@@@ static void wacom_wac_finger_usage_mapp
          {
                struct wacom *wacom = hid_get_drvdata(hdev);
                struct wacom_wac *wacom_wac = &wacom->wacom_wac;
---------       struct input_dev *input = wacom_wac->input;
+++++++++       struct wacom_features *features = &wacom_wac->features;
                unsigned touch_max = wacom_wac->features.touch_max;
          
                switch (usage->hid) {
                case HID_GD_X:
+++++++++               features->last_slot_field = usage->hid;
                        if (touch_max == 1)
                                wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4);
                        else
                                                ABS_MT_POSITION_X, 4);
                        break;
                case HID_GD_Y:
+++++++++               features->last_slot_field = usage->hid;
                        if (touch_max == 1)
                                wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4);
                        else
                                                ABS_MT_POSITION_Y, 4);
                        break;
                case HID_DG_CONTACTID:
---------               input_mt_init_slots(input, wacom_wac->features.touch_max,
---------                       INPUT_MT_DIRECT);
+++++++++               features->last_slot_field = usage->hid;
                        break;
                case HID_DG_INRANGE:
+++++++++               features->last_slot_field = usage->hid;
                        break;
                case HID_DG_INVERT:
+++++++++               features->last_slot_field = usage->hid;
                        break;
                case HID_DG_TIPSWITCH:
+++++++++               features->last_slot_field = usage->hid;
                        wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0);
                        break;
                }
          }
          
+++++++++ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
+++++++++               struct input_dev *input)
+++++++++ {
+++++++++       struct hid_data *hid_data = &wacom_wac->hid_data;
+++++++++       bool mt = wacom_wac->features.touch_max > 1;
+++++++++       bool prox = hid_data->tipswitch &&
+++++++++                   !wacom_wac->shared->stylus_in_proximity;
+++++++++ 
+++++++++       if (mt) {
+++++++++               int slot;
+++++++++ 
+++++++++               slot = input_mt_get_slot_by_key(input, hid_data->id);
+++++++++               input_mt_slot(input, slot);
+++++++++               input_mt_report_slot_state(input, MT_TOOL_FINGER, prox);
+++++++++       }
+++++++++       else {
+++++++++               input_report_key(input, BTN_TOUCH, prox);
+++++++++       }
+++++++++ 
+++++++++       if (prox) {
+++++++++               input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X,
+++++++++                                hid_data->x);
+++++++++               input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y,
+++++++++                                hid_data->y);
+++++++++       }
+++++++++ }
+++++++++ 
          static int wacom_wac_finger_event(struct hid_device *hdev,
                        struct hid_field *field, struct hid_usage *usage, __s32 value)
          {
                }
          
          
+++++++++       if (usage->usage_index + 1 == field->report_count) {
+++++++++               if (usage->hid == wacom_wac->features.last_slot_field)
+++++++++                       wacom_wac_finger_slot(wacom_wac, wacom_wac->input);
+++++++++       }
+++++++++ 
                return 0;
          }
          
--------- static void wacom_wac_finger_mt_report(struct wacom_wac *wacom_wac,
---------               struct input_dev *input, bool touch)
+++++++++ static int wacom_wac_finger_count_touches(struct hid_device *hdev)
          {
---------       int slot;
---------       struct hid_data *hid_data = &wacom_wac->hid_data;
+++++++++       struct wacom *wacom = hid_get_drvdata(hdev);
+++++++++       struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+++++++++       struct input_dev *input = wacom_wac->input;
+++++++++       unsigned touch_max = wacom_wac->features.touch_max;
+++++++++       int count = 0;
+++++++++       int i;
          
---------       slot = input_mt_get_slot_by_key(input, hid_data->id);
+++++++++       if (touch_max == 1)
+++++++++               return wacom_wac->hid_data.tipswitch &&
+++++++++                      !wacom_wac->shared->stylus_in_proximity;
          
---------       input_mt_slot(input, slot);
---------       input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
---------       if (touch) {
---------               input_report_abs(input, ABS_MT_POSITION_X, hid_data->x);
---------               input_report_abs(input, ABS_MT_POSITION_Y, hid_data->y);
+++++++++       for (i = 0; i < input->mt->num_slots; i++) {
+++++++++               struct input_mt_slot *ps = &input->mt->slots[i];
+++++++++               int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
+++++++++               if (id >= 0)
+++++++++                       count++;
                }
---------       input_mt_sync_frame(input);
--------- }
          
--------- static void wacom_wac_finger_single_touch_report(struct wacom_wac *wacom_wac,
---------               struct input_dev *input, bool touch)
--------- {
---------       struct hid_data *hid_data = &wacom_wac->hid_data;
--------- 
---------       if (touch) {
---------               input_report_abs(input, ABS_X, hid_data->x);
---------               input_report_abs(input, ABS_Y, hid_data->y);
---------       }
---------       input_report_key(input, BTN_TOUCH, touch);
+++++++++       return count;
          }
          
          static void wacom_wac_finger_report(struct hid_device *hdev,
                struct wacom *wacom = hid_get_drvdata(hdev);
                struct wacom_wac *wacom_wac = &wacom->wacom_wac;
                struct input_dev *input = wacom_wac->input;
---------       bool touch = wacom_wac->hid_data.tipswitch &&
---------                    !wacom_wac->shared->stylus_in_proximity;
                unsigned touch_max = wacom_wac->features.touch_max;
          
                if (touch_max > 1)
---------               wacom_wac_finger_mt_report(wacom_wac, input, touch);
---------       else
---------               wacom_wac_finger_single_touch_report(wacom_wac, input, touch);
+++++++++               input_mt_sync_frame(input);
+++++++++ 
                input_sync(input);
          
                /* keep touch state for pen event */
---------       wacom_wac->shared->touch_down = touch;
+++++++++       wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(hdev);
          }
          
          #define WACOM_PEN_FIELD(f)    (((f)->logical == HID_DG_STYLUS) || \
---------                                ((f)->physical == HID_DG_STYLUS))
+++++++++                                ((f)->physical == HID_DG_STYLUS) || \
+++++++++                                ((f)->application == HID_DG_PEN))
          #define WACOM_FINGER_FIELD(f) (((f)->logical == HID_DG_FINGER) || \
---------                                ((f)->physical == HID_DG_FINGER))
+++++++++                                ((f)->physical == HID_DG_FINGER) || \
+++++++++                                ((f)->application == HID_DG_TOUCHSCREEN))
          
          void wacom_wac_usage_mapping(struct hid_device *hdev,
                        struct hid_field *field, struct hid_usage *usage)
@@@@@@@@@@@ -1681,7 -1681,7 -1681,7 -1681,7 -1681,7 -1681,7 -1681,7 -1681,7 -1681,7 -1714,9 +1714,9 @@@@@@@@@@@ static int wacom_bpt_pen(struct wacom_w
                    return 0;
          
                if (data[0] == WACOM_REPORT_USB) {
---------               if (features->type == INTUOSHT && features->touch_max) {
+++++++++               if (features->type == INTUOSHT &&
+++++++++                   wacom->shared->touch_input &&
+++++++++                   features->touch_max) {
                                input_report_switch(wacom->shared->touch_input,
                                                    SW_MUTE_DEVICE, data[8] & 0x40);
                                input_sync(wacom->shared->touch_input);
@@@@@@@@@@@ -1774,7 -1774,7 -1774,7 -1774,7 -1774,7 -1774,7 -1774,7 -1774,7 -1774,7 -1809,8 +1809,8 @@@@@@@@@@@ static int wacom_wireless_irq(struct wa
                        int pid, battery, ps_connected;
          
                        if ((wacom->shared->type == INTUOSHT) &&
---------                               wacom->shared->touch_max) {
+++++++++                   wacom->shared->touch_input &&
+++++++++                   wacom->shared->touch_max) {
                                input_report_switch(wacom->shared->touch_input,
                                                SW_MUTE_DEVICE, data[5] & 0x40);
                                input_sync(wacom->shared->touch_input);
@@@@@@@@@@@ -1838,6 -1838,6 -1838,6 -1838,6 -1838,6 -1838,6 -1838,6 -1838,6 -1838,6 -1874,7 +1874,7 @@@@@@@@@@@ void wacom_wac_irq(struct wacom_wac *wa
                        break;
          
                case DTUS:
+++++++++       case DTUSX:
                        sync = wacom_dtus_irq(wacom_wac);
                        break;
          
@@@@@@@@@@@ -1926,8 -1926,8 -1926,8 -1926,8 -1926,8 -1926,8 -1926,8 -1926,8 -1926,8 -1963,10 +1963,10 @@@@@@@@@@@ static void wacom_setup_cintiq(struct w
                input_set_abs_params(input_dev, ABS_DISTANCE,
                                     0, wacom_wac->features.distance_max, 0, 0);
                input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
---------       input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
---------       input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
+++++++++       input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0);
+++++++++       input_abs_set_res(input_dev, ABS_TILT_X, 57);
+++++++++       input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0);
+++++++++       input_abs_set_res(input_dev, ABS_TILT_Y, 57);
          }
          
          static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
                __set_bit(BTN_TOOL_LENS, input_dev->keybit);
          
                input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
+++++++++       input_abs_set_res(input_dev, ABS_RZ, 287);
                input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
          }
          
@@@@@@@@@@@ -2029,7 -2029,7 -2029,7 -2029,7 -2029,7 -2029,7 -2029,7 -2029,7 -2029,7 -2069,7 +2069,7 @@@@@@@@@@@ static void wacom_abs_set_axis(struct i
                }
          }
          
--------- int wacom_setup_input_capabilities(struct input_dev *input_dev,
+++++++++ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
                                           struct wacom_wac *wacom_wac)
          {
                struct wacom_features *features = &wacom_wac->features;
          
                switch (features->type) {
                case WACOM_MO:
---------               input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
---------               /* fall through */
--------- 
                case WACOM_G4:
                        /* fall through */
          
          
                case WACOM_24HD:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
                        input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
                        /* fall through */
          
                case WACOM_BEE:
                case CINTIQ:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
          
                        __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
          
          
                case WACOM_13HD:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
                        __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
                        wacom_setup_cintiq(wacom_wac);
                        break;
                case INTUOS3L:
                case INTUOS3S:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
                        /* fall through */
          
                case INTUOS:
                                                      0, 0);
          
                                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++                       input_abs_set_res(input_dev, ABS_Z, 287);
          
                                wacom_setup_intuos(wacom_wac);
                        } else if (features->device_type == BTN_TOOL_FINGER) {
                case INTUOS4L:
                case INTUOS4S:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
                        wacom_setup_intuos(wacom_wac);
          
                        __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                        /* fall through */
          
                case DTUS:
+++++++++       case DTUSX:
                case PL:
                case DTU:
                        __set_bit(BTN_TOOL_PEN, input_dev->keybit);
                                        __clear_bit(ABS_X, input_dev->absbit);
                                        __clear_bit(ABS_Y, input_dev->absbit);
                                        __clear_bit(BTN_TOUCH, input_dev->keybit);
+++++++++ 
+++++++++                               /* PAD is setup by wacom_setup_pad_input_capabilities later */
+++++++++                               return 1;
                                }
                        } else if (features->device_type == BTN_TOOL_PEN) {
                                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
          
                case CINTIQ_HYBRID:
                        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+++++++++               input_abs_set_res(input_dev, ABS_Z, 287);
                        __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
          
                        wacom_setup_cintiq(wacom_wac);
@@@@@@@@@@@ -2303,9 -2303,9 -2303,9 -2303,9 -2303,9 -2303,9 -2303,9 -2303,9 -2303,9 -2351,7 +2351,7 @@@@@@@@@@@ int wacom_setup_pad_input_capabilities(
          
                case WACOM_G4:
                        __set_bit(BTN_BACK, input_dev->keybit);
---------               __set_bit(BTN_LEFT, input_dev->keybit);
                        __set_bit(BTN_FORWARD, input_dev->keybit);
---------               __set_bit(BTN_RIGHT, input_dev->keybit);
                        input_set_capability(input_dev, EV_REL, REL_WHEEL);
                        break;
          
                case INTUOSPS:
                        /* touch interface does not have the pad device */
                        if (features->device_type != BTN_TOOL_PEN)
---------                       return 1;
+++++++++                       return -ENODEV;
          
                        for (i = 0; i < 7; i++)
                                __set_bit(BTN_0 + i, input_dev->keybit);
                case INTUOSHT:
                case BAMBOO_PT:
                        /* pad device is on the touch interface */
---------               if (features->device_type != BTN_TOOL_FINGER)
---------                       return 1;
+++++++++               if ((features->device_type != BTN_TOOL_FINGER) ||
+++++++++                   /* Bamboo Pen only tablet does not have pad */
+++++++++                   ((features->type == BAMBOO_PT) && !features->touch_max))
+++++++++                       return -ENODEV;
          
                        __clear_bit(ABS_MISC, input_dev->absbit);
          
          
                default:
                        /* no pad supported */
---------               return 1;
+++++++++               return -ENODEV;
                }
                return 0;
          }
@@@@@@@@@@@ -2664,11 -2664,11 -2664,11 -2664,11 -2664,11 -2664,11 -2664,11 -2664,11 -2664,11 -2712,13 +2712,13 @@@@@@@@@@@ static const struct wacom_features waco
                  INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16,
                  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
          static const struct wacom_features wacom_features_0xF4 =
---------       { "Wacom Cintiq 24HD", 104280, 65400, 2047, 63,
---------         WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
+++++++++       { "Wacom Cintiq 24HD", 104080, 65200, 2047, 63,
+++++++++         WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
          static const struct wacom_features wacom_features_0xF8 =
---------       { "Wacom Cintiq 24HD touch", 104280, 65400, 2047, 63, /* Pen */
---------         WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
+++++++++       { "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */
+++++++++         WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
          static const struct wacom_features wacom_features_0xF6 =
                { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
@@@@@@@@@@@ -2684,8 -2684,8 -2684,8 -2684,8 -2684,8 -2684,8 -2684,8 -2684,8 -2684,8 -2734,9 +2734,9 @@@@@@@@@@@ static const struct wacom_features waco
                { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,
                  WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
          static const struct wacom_features wacom_features_0x304 =
---------       { "Wacom Cintiq 13HD", 59352, 33648, 1023, 63,
---------         WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
+++++++++       { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
+++++++++         WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
          static const struct wacom_features wacom_features_0xC7 =
                { "Wacom DTU1931", 37832, 30305, 511, 0,
                  PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@@@@@@@@@@ -2697,28 -2697,28 -2697,28 -2697,28 -2697,28 -2697,28 -2697,28 -2697,28 -2697,28 -2748,38 +2748,38 @@@@@@@@@@@ static const struct wacom_features waco
                { "Wacom DTU1631", 34623, 19553, 511, 0,
                  DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
          static const struct wacom_features wacom_features_0xFB =
---------       { "Wacom DTU1031", 22096, 13960, 511, 0,
---------         DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+++++++++       { "Wacom DTU1031", 21896, 13760, 511, 0,
+++++++++         DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+++++++++         WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
+++++++++ static const struct wacom_features wacom_features_0x32F =
+++++++++       { "Wacom DTU1031X", 22472, 12728, 511, 0,
+++++++++         DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+++++++++         WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
          static const struct wacom_features wacom_features_0x57 =
                { "Wacom DTK2241", 95640, 54060, 2047, 63,
---------         DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
+++++++++         DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
          static const struct wacom_features wacom_features_0x59 = /* Pen */
                { "Wacom DTH2242", 95640, 54060, 2047, 63,
---------         DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
+++++++++         DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };
          static const struct wacom_features wacom_features_0x5D = /* Touch */
                { "Wacom DTH2242",       .type = WACOM_24HDT,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10,
                  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
          static const struct wacom_features wacom_features_0xCC =
---------       { "Wacom Cintiq 21UX2", 87000, 65400, 2047, 63,
---------         WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
+++++++++       { "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63,
+++++++++         WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
          static const struct wacom_features wacom_features_0xFA =
---------       { "Wacom Cintiq 22HD", 95640, 54060, 2047, 63,
---------         WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 };
+++++++++       { "Wacom Cintiq 22HD", 95440, 53860, 2047, 63,
+++++++++         WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
          static const struct wacom_features wacom_features_0x5B =
---------       { "Wacom Cintiq 22HDT", 95640, 54060, 2047, 63,
---------         WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
+++++++++       { "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63,
+++++++++         WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
          static const struct wacom_features wacom_features_0x5E =
                { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
@@@@@@@@@@@ -2863,21 -2863,21 -2863,21 -2863,21 -2863,21 -2863,21 -2863,21 -2863,21 -2863,21 -2924,27 +2924,27 @@@@@@@@@@@ static const struct wacom_features waco
                { "ISD-V4", 12800, 8000, 255, 0,
                  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
          static const struct wacom_features wacom_features_0x307 =
---------       { "Wacom ISDv5 307", 59352, 33648, 2047, 63,
---------         CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
+++++++++       { "Wacom ISDv5 307", 59152, 33448, 2047, 63,
+++++++++         CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
          static const struct wacom_features wacom_features_0x309 =
                { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,
                  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
          static const struct wacom_features wacom_features_0x30A =
---------       { "Wacom ISDv5 30A", 59352, 33648, 2047, 63,
---------         CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200,
+++++++++       { "Wacom ISDv5 30A", 59152, 33448, 2047, 63,
+++++++++         CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++         WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };
          static const struct wacom_features wacom_features_0x30C =
                { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */
                  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
                  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
+++++++++ static const struct wacom_features wacom_features_0x323 =
+++++++++       { "Wacom Intuos P M", 21600, 13500, 1023, 31,
+++++++++         INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+++++++++         .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
          
          static const struct wacom_features wacom_features_HID_ANY_ID =
                { "Wacom HID", .type = HID_GENERIC };
@@@@@@@@@@@ -3022,11 -3022,10 -3022,10 -3022,10 -3022,10 -3022,10 -3022,10 -3022,10 -3022,10 -3089,12 +3089,13 @@@@@@@@@@@ const struct hid_device_id wacom_ids[] 
                { USB_DEVICE_WACOM(0x314) },
                { USB_DEVICE_WACOM(0x315) },
                { USB_DEVICE_WACOM(0x317) },
+++++++++       { USB_DEVICE_WACOM(0x323) },
+++++++++       { USB_DEVICE_WACOM(0x32F) },
                { USB_DEVICE_WACOM(0x4001) },
                { USB_DEVICE_WACOM(0x4004) },
                { USB_DEVICE_WACOM(0x5000) },
                { USB_DEVICE_WACOM(0x5002) },
 +++++++++      { USB_DEVICE_LENOVO(0x6004) },
          
                { USB_DEVICE_WACOM(HID_ANY_ID) },
                { }
diff --combined include/linux/hid.h
index 5b1ff6110e256388a3f170f64ad4d9b78c686654,2366fda010c8dccf9dd07c4f3fde9b01326e20c8,78ea9bf941cd3352def7eaff6f26304beb1e2f7e,78ea9bf941cd3352def7eaff6f26304beb1e2f7e,7d6e0556302ad7cb417a00b10f9fd7e8f8dea7cc,78ea9bf941cd3352def7eaff6f26304beb1e2f7e,58a89ed86acc2cace0486c1faa6fb3239ff2a1ab,78ea9bf941cd3352def7eaff6f26304beb1e2f7e,78ea9bf941cd3352def7eaff6f26304beb1e2f7e,78ea9bf941cd3352def7eaff6f26304beb1e2f7e..06c4607744f637156d14a667b9b5b55f0a37b693
@@@@@@@@@@@ -234,6 -234,6 -234,6 -234,6 -234,6 -234,6 -234,33 -234,6 -234,6 -234,6 +234,33 @@@@@@@@@@@ struct hid_item 
          #define HID_DG_BARRELSWITCH   0x000d0044
          #define HID_DG_ERASER         0x000d0045
          #define HID_DG_TABLETPICK     0x000d0046
++++++ +++
++++++ +++#define HID_CP_CONSUMERCONTROL        0x000c0001
++++++ +++#define HID_CP_NUMERICKEYPAD  0x000c0002
++++++ +++#define HID_CP_PROGRAMMABLEBUTTONS    0x000c0003
++++++ +++#define HID_CP_MICROPHONE     0x000c0004
++++++ +++#define HID_CP_HEADPHONE      0x000c0005
++++++ +++#define HID_CP_GRAPHICEQUALIZER       0x000c0006
++++++ +++#define HID_CP_FUNCTIONBUTTONS        0x000c0036
++++++ +++#define HID_CP_SELECTION      0x000c0080
++++++ +++#define HID_CP_MEDIASELECTION 0x000c0087
++++++ +++#define HID_CP_SELECTDISC     0x000c00ba
++++++ +++#define HID_CP_PLAYBACKSPEED  0x000c00f1
++++++ +++#define HID_CP_PROXIMITY      0x000c0109
++++++ +++#define HID_CP_SPEAKERSYSTEM  0x000c0160
++++++ +++#define HID_CP_CHANNELLEFT    0x000c0161
++++++ +++#define HID_CP_CHANNELRIGHT   0x000c0162
++++++ +++#define HID_CP_CHANNELCENTER  0x000c0163
++++++ +++#define HID_CP_CHANNELFRONT   0x000c0164
++++++ +++#define HID_CP_CHANNELCENTERFRONT     0x000c0165
++++++ +++#define HID_CP_CHANNELSIDE    0x000c0166
++++++ +++#define HID_CP_CHANNELSURROUND        0x000c0167
++++++ +++#define HID_CP_CHANNELLOWFREQUENCYENHANCEMENT 0x000c0168
++++++ +++#define HID_CP_CHANNELTOP     0x000c0169
++++++ +++#define HID_CP_CHANNELUNKNOWN 0x000c016a
++++++ +++#define HID_CP_APPLICATIONLAUNCHBUTTONS       0x000c0180
++++++ +++#define HID_CP_GENERICGUIAPPLICATIONCONTROLS  0x000c0200
++++++ +++
          #define HID_DG_CONFIDENCE     0x000d0047
          #define HID_DG_WIDTH          0x000d0048
          #define HID_DG_HEIGHT         0x000d0049
           * Vendor specific HID device groups
           */
          #define HID_GROUP_RMI                         0x0100
 --- -----
 --- -----/*
 --- ----- * Vendor specific HID device groups
 --- ----- */
          #define HID_GROUP_WACOM                               0x0101
++++ +++++#define HID_GROUP_LOGITECH_DJ_DEVICE          0x0102
          
          /*
           * This is the global environment of the parser. This information is
@@@@@@@@@@@ -1059,6 -1063,17 -1063,6 -1063,6 -1060,6 -1063,6 -1090,6 -1063,6 -1063,6 -1063,6 +1087,17 @@@@@@@@@@@ static inline void hid_hw_wait(struct h
                        hdev->ll_driver->wait(hdev);
          }
          
+ ++++++++/**
+ ++++++++ * hid_report_len - calculate the report length
+ ++++++++ *
+ ++++++++ * @report: the report we want to know the length
+ ++++++++ */
+ ++++++++static inline int hid_report_len(struct hid_report *report)
+ ++++++++{
+ ++++++++      /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
+ ++++++++      return ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ ++++++++}
+ ++++++++
          int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
                        int interrupt);