Merge branches 'for-4.0/upstream-fixes', 'for-4.1/genius', 'for-4.1/huion-uclogic...
authorJiri Kosina <jkosina@suse.cz>
Mon, 13 Apr 2015 21:41:15 +0000 (23:41 +0200)
committerJiri Kosina <jkosina@suse.cz>
Mon, 13 Apr 2015 21:41:15 +0000 (23:41 +0200)
1  2  3  4  5  6  7  8  9  10  11 
drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-ids.h
drivers/hid/hid-multitouch.c
drivers/hid/hid-sony.c
drivers/hid/usbhid/hid-quirks.c
drivers/input/input-mt.c
include/linux/hid.h

diff --combined drivers/hid/Kconfig
@@@@@@@@@@@@ -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 -92,7 +92,7 @@@@@@@@@@@@ menu "Special HID drivers
                depends on HID
           
           config HID_A4TECH
---- ------     tristate "A4 tech mice" if EXPERT
++++ ++++++     tristate "A4 tech mice"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 -113,7 +113,7 @@@@@@@@@@@@ config HID_ACRUX_F
                game controllers.
           
           config HID_APPLE
---- ------     tristate "Apple {i,Power,Mac}Books" if EXPERT
++++ ++++++     tristate "Apple {i,Power,Mac}Books"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 -141,7 +141,7 @@@@@@@@@@@@ config HID_AUREA
                Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
           
           config HID_BELKIN
---- ------     tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT
++++ ++++++     tristate "Belkin Flip KVM and Wireless keyboard"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 -158,14 +158,14 @@@@@@@@@@@@ config HID_BETOP_F
                 - BETOP 2185 PC & BFM MODE
           
           config HID_CHERRY
---- ------     tristate "Cherry Cymotion keyboard" if EXPERT
++++ ++++++     tristate "Cherry Cymotion keyboard"
                depends on HID
                default !EXPERT
                ---help---
                Support for Cherry Cymotion keyboard.
           
           config HID_CHICONY
---- ------     tristate "Chicony Tactical pad" if EXPERT
++++ ++++++     tristate "Chicony Tactical pad"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 -196,7 +196,7 @@@@@@@@@@@@ config HID_CP211
                customizable USB descriptor fields are exposed as sysfs attributes.
           
           config HID_CYPRESS
---- ------     tristate "Cypress mouse and barcode readers" if EXPERT
++++ ++++++     tristate "Cypress mouse and barcode readers"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 -245,7 +245,7 @@@@@@@@@@@@ config HID_EL
                different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO.
           
           config HID_EZKEY
---- ------     tristate "Ezkey BTC 8193 keyboard" if EXPERT
++++ ++++++     tristate "Ezkey BTC 8193 keyboard"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -286,12 -286,12 -286,6 -286,12 -286,12 -286,12 -286,12 -286,12 -286,12 -286,12 -286,12 +286,6 @@@@@@@@@@@@ config HID_GT683
                Currently the following devices are know to be supported:
                  - MSI GT683R
           
-- --------config HID_HUION
-- --------     tristate "Huion tablets"
-- --------     depends on USB_HID
-- --------     ---help---
-- --------     Support for Huion 580 tablet.
-- --------
           config HID_KEYTOUCH
                tristate "Keytouch HID devices"
                depends on HID
@@@@@@@@@@@@ -312,9 -312,9 -306,9 -312,9 -312,9 -312,9 -312,9 -312,9 -312,9 -312,9 -312,9 +306,9 @@@@@@@@@@@@ config HID_KY
           
           config HID_UCLOGIC
                tristate "UC-Logic"
-- --------     depends on HID
++ ++++++++     depends on USB_HID
                ---help---
-- --------     Support for UC-Logic tablets.
++ ++++++++     Support for UC-Logic and Huion tablets.
           
           config HID_WALTOP
                tristate "Waltop"
@@@@@@@@@@@@ -344,7 -344,7 -338,7 -344,7 -344,7 -344,7 -344,7 -344,7 -344,7 -344,7 -344,7 +338,7 @@@@@@@@@@@@ config HID_TWINHA
                Support for Twinhan IR remote control.
           
           config HID_KENSINGTON
---- ------     tristate "Kensington Slimblade Trackball" if EXPERT
++++ ++++++     tristate "Kensington Slimblade Trackball"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -372,7 -372,7 -366,7 -372,7 -372,7 -372,7 -372,7 -372,7 -372,7 -372,7 -372,7 +366,7 @@@@@@@@@@@@ config HID_LENOV
                - ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)
           
           config HID_LOGITECH
---- ------     tristate "Logitech devices" if EXPERT
++++ ++++++     tristate "Logitech devices"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -461,14 -461,14 -455,14 -461,14 -461,14 -461,14 -461,14 -461,14 -461,14 -461,14 -461,14 +455,14 @@@@@@@@@@@@ config HID_MAGICMOUS
                Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad.
           
           config HID_MICROSOFT
---- ------     tristate "Microsoft non-fully HID-compliant devices" if EXPERT
++++ ++++++     tristate "Microsoft non-fully HID-compliant devices"
                depends on HID
                default !EXPERT
                ---help---
                Support for Microsoft devices that are not fully compliant with HID standard.
           
           config HID_MONTEREY
---- ------     tristate "Monterey Genius KB29E keyboard" if EXPERT
++++ ++++++     tristate "Monterey Genius KB29E keyboard"
                depends on HID
                default !EXPERT
                ---help---
@@@@@@@@@@@@ -638,7 -638,7 -632,7 -638,7 -638,7 -638,7 -638,7 -638,7 -638,7 -638,6 -638,7 +632,6 @@@@@@@@@@@@ config HID_PICOLCD_CI
           
           config HID_PLANTRONICS
                tristate "Plantronics USB HID Driver"
--------- -     default !EXPERT
                depends on HID
                ---help---
                Provides HID support for Plantronics telephony devices.
diff --combined drivers/hid/hid-core.c
@@@@@@@@@@@@ -1562,12 -1562,12 -1562,12 -1562,12 -1562,12 -1562,12 -1562,12 -1562,12 -1562,12 -1562,26 -1562,12 +1562,26 @@@@@@@@@@@@ read_report_descriptor(struct file *fil
                return count;
           }
           
+++++++++ +static ssize_t
+++++++++ +show_country(struct device *dev, struct device_attribute *attr,
+++++++++ +             char *buf)
+++++++++ +{
+++++++++ +     struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+++++++++ +
+++++++++ +     return sprintf(buf, "%02x\n", hdev->country & 0xff);
+++++++++ +}
+++++++++ +
           static struct bin_attribute dev_bin_attr_report_desc = {
                .attr = { .name = "report_descriptor", .mode = 0444 },
                .read = read_report_descriptor,
                .size = HID_MAX_DESCRIPTOR_SIZE,
           };
           
+++++++++ +static struct device_attribute dev_attr_country = {
+++++++++ +     .attr = { .name = "country", .mode = 0444 },
+++++++++ +     .show = show_country,
+++++++++ +};
+++++++++ +
           int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
           {
                static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
                        bus = "<UNKNOWN>";
                }
           
+++++++++ +     ret = device_create_file(&hdev->dev, &dev_attr_country);
+++++++++ +     if (ret)
+++++++++ +             hid_warn(hdev,
+++++++++ +                      "can't create sysfs country code attribute err: %d\n", ret);
+++++++++ +
                ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
                if (ret)
                        hid_warn(hdev,
@@@@@@@@@@@@ -1661,6 -1661,6 -1661,6 -1661,6 -1661,6 -1661,6 -1661,6 -1661,6 -1661,6 -1680,7 -1661,6 +1680,7 @@@@@@@@@@@@ EXPORT_SYMBOL_GPL(hid_connect)
           
           void hid_disconnect(struct hid_device *hdev)
           {
+++++++++ +     device_remove_file(&hdev->dev, &dev_attr_country);
                device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
                if (hdev->claimed & HID_CLAIMED_INPUT)
                        hidinput_disconnect(hdev);
@@@@@@@@@@@@ -1824,6 -1824,7 -1824,6 -1824,6 -1824,6 -1824,6 -1824,6 -1824,6 -1824,6 -1844,6 -1824,6 +1844,7 @@@@@@@@@@@@ static const struct hid_device_id hid_h
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
                { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
+ +++++++++     { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
           #if IS_ENABLED(CONFIG_HID_LENOVO)
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) },
 +   + +++      { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE7K) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
           #endif
           #if IS_ENABLED(CONFIG_HID_SAITEK)
                { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
 +   + +++      { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) },
                { 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) },
                { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
                { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
 +++++++++      { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
                { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
                { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
                { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
diff --combined drivers/hid/hid-debug.c
@@@@@@@@@@@@ -165,6 -165,6 -165,6 -165,6 -165,6 -165,6 -165,7 -165,6 -165,6 -165,6 -165,6 +165,7 @@@@@@@@@@@@ static const struct hid_usage_entry hid
               {0, 0x53, "DeviceIndex"},
               {0, 0x54, "ContactCount"},
               {0, 0x55, "ContactMaximumNumber"},
++++++ ++++    {0, 0x59, "ButtonType"},
               {0, 0x5A, "SecondaryBarrelSwitch"},
               {0, 0x5B, "TransducerSerialNumber"},
             { 15, 0, "PhysicalInterfaceDevice" },
@@@@@@@@@@@@ -1127,7 -1127,7 -1127,7 -1127,7 -1127,7 -1127,7 -1128,7 -1127,7 -1127,7 -1127,8 -1127,7 +1128,8 @@@@@@@@@@@@ static ssize_t hid_debug_events_read(st
           
                                        if (!list->hdev || !list->hdev->debug) {
                                                ret = -EIO;
--------- -                                     break;
+++++++++ +                                     set_current_state(TASK_RUNNING);
+++++++++ +                                     goto out;
                                        }
           
                                        /* allow O_NONBLOCK from other threads */
diff --combined drivers/hid/hid-ids.h
           #define USB_DEVICE_ID_UGCI_FLYING    0x0020
           #define USB_DEVICE_ID_UGCI_FIGHTING  0x0030
           
          -#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE     0x0a4a
 +++++++++ #define USB_VENDOR_ID_HP             0x03f0
 ++++++++++#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A        0x0a4a
 ++++++++++#define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A        0x0b4a
 +++++++++ #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE               0x134a
 +++++++++ 
           #define USB_VENDOR_ID_HUION          0x256c
           #define USB_DEVICE_ID_HUION_TABLET   0x006e
           
           #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X     0x5011
           #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2   0x501a
           #define USB_DEVICE_ID_KYE_EASYPEN_M610X      0x5013
+ +++++++++#define USB_DEVICE_ID_KYE_PENSKETCH_M912     0x5015
           
           #define USB_VENDOR_ID_LABTEC         0x1020
           #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD       0x0006
           #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_C077  0xc007
           #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_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
 ++++++++++#define USB_DEVICE_ID_LOGITECH_MOUSE_C01A    0xc01a
 ++++++++++#define USB_DEVICE_ID_LOGITECH_MOUSE_C05A    0xc05a
 ++++++++++#define USB_DEVICE_ID_LOGITECH_MOUSE_C06A    0xc06a
           #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD        0xc20a
           #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD     0xc211
           #define USB_DEVICE_ID_LOGITECH_EXTREME_3D    0xc215
           #define USB_DEVICE_ID_MS_LK6K                0x00f9
           #define USB_DEVICE_ID_MS_PRESENTER_8K_BT     0x0701
           #define USB_DEVICE_ID_MS_PRESENTER_8K_USB    0x0713
 +   + +++ #define USB_DEVICE_ID_MS_NE7K                0x071d
           #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K    0x0730
           #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500  0x076c
           #define USB_DEVICE_ID_MS_SURFACE_PRO_2   0x0799
           #define USB_VENDOR_ID_SAITEK         0x06a3
           #define USB_DEVICE_ID_SAITEK_RUMBLEPAD       0xff17
           #define USB_DEVICE_ID_SAITEK_PS1000  0x0621
 +   + +++ #define USB_DEVICE_ID_SAITEK_RAT7_OLD        0x0ccb
           #define USB_DEVICE_ID_SAITEK_RAT7    0x0cd7
           #define USB_DEVICE_ID_SAITEK_MMO7    0x0cd0
           
           #define USB_VENDOR_ID_TIVO           0x150a
           #define USB_DEVICE_ID_TIVO_SLIDE_BT  0x1200
           #define USB_DEVICE_ID_TIVO_SLIDE     0x1201
 +++++++++ #define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
           
           #define USB_VENDOR_ID_TOPSEED                0x0766
           #define USB_DEVICE_ID_TOPSEED_CYBERLINK      0x0204
           #define USB_DEVICE_ID_ZYTRONIC_ZXY100        0x0005
           
           #define USB_VENDOR_ID_PRIMAX 0x0461
 ++++++++++#define USB_DEVICE_ID_PRIMAX_MOUSE_4D22      0x4d22
           #define USB_DEVICE_ID_PRIMAX_KEYBOARD        0x4e05
           
           
           #include <linux/hid.h>
           #include <linux/module.h>
           #include <linux/slab.h>
--------- -#include <linux/usb.h>
           #include <linux/input/mt.h>
           #include <linux/string.h>
           
@@@@@@@@@@@@ -72,6 -72,6 -72,6 -72,6 -72,6 -72,6 -72,8 -72,6 -72,6 -71,6 -72,6 +71,8 @@@@@@@@@@@@ MODULE_LICENSE("GPL")
           #define MT_INPUTMODE_TOUCHSCREEN     0x02
           #define MT_INPUTMODE_TOUCHPAD                0x03
           
++++++ ++++#define MT_BUTTONTYPE_CLICKPAD               0
++++++ ++++
           struct mt_slot {
                __s32 x, y, cx, cy, p, w, h;
                __s32 contactid;        /* the device ContactID assigned to this slot */
@@@@@@@@@@@@ -116,6 -116,6 -116,6 -116,6 -116,6 -116,6 -118,8 -116,6 -116,6 -115,6 -116,6 +117,8 @@@@@@@@@@@@ struct mt_device 
                __u8 touches_by_report; /* how many touches are present in one report:
                                        * 1 means we should use a serial protocol
                                        * > 1 means hybrid (multitouch) protocol */
++++++ ++++     __u8 buttons_count;     /* number of physical buttons per touchpad */
++++++ ++++     bool is_buttonpad;      /* is this device a button pad? */
                bool serial_maybe;      /* need to check for serial protocol */
                bool curvalid;          /* is the current contact valid? */
                unsigned mt_flags;      /* flags to pass to input-mt */
@@@@@@@@@@@@ -333,6 -333,6 -333,6 -333,6 -333,6 -333,6 -337,16 -333,6 -333,6 -332,6 -333,6 +336,16 @@@@@@@@@@@@ static void mt_feature_mapping(struct h
                                /* check if the maxcontacts is given by the class */
                                td->maxcontacts = td->mtclass.maxcontacts;
           
++++++ ++++             break;
++++++ ++++     case HID_DG_BUTTONTYPE:
++++++ ++++             if (usage->usage_index >= field->report_count) {
++++++ ++++                     dev_err(&hdev->dev, "HID_DG_BUTTONTYPE out of range\n");
++++++ ++++                     break;
++++++ ++++             }
++++++ ++++
++++++ ++++             if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD)
++++++ ++++                     td->is_buttonpad = true;
++++++ ++++
                        break;
                }
           }
@@@@@@@@@@@@ -379,6 -379,6 -379,6 -379,6 -379,6 -379,6 -393,10 -379,6 -379,6 -378,6 -379,6 +392,10 @@@@@@@@@@@@ static int mt_touch_input_mapping(struc
                        td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
                }
           
++++++ ++++     /* count the buttons on touchpads */
++++++ ++++     if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
++++++ ++++             td->buttons_count++;
++++++ ++++
                if (usage->usage_index)
                        prev_usage = &field->usage[usage->usage_index - 1];
           
@@@@@@@@@@@@ -728,6 -728,6 -728,6 -728,6 -728,6 -728,6 -746,13 -728,6 -728,6 -727,6 -728,6 +745,13 @@@@@@@@@@@@ static void mt_touch_input_configured(s
                if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
                        td->mt_flags |= INPUT_MT_DROP_UNUSED;
           
++++++ ++++     /* check for clickpads */
++++++ ++++     if ((td->mt_flags & INPUT_MT_POINTER) && (td->buttons_count == 1))
++++++ ++++             td->is_buttonpad = true;
++++++ ++++
++++++ ++++     if (td->is_buttonpad)
++++++ ++++             __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
++++++ ++++
                input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
           
                td->mt_flags = 0;
diff --combined drivers/hid/hid-sony.c
@@@@@@@@@@@@ -802,9 -802,9 -802,9 -802,9 -802,9 -802,9 -802,9 -802,9 -802,10 -802,9 -802,9 +802,10 @@@@@@@@@@@@ union sixaxis_output_report_01 
           #define DS4_REPORT_0x05_SIZE 32
           #define DS4_REPORT_0x11_SIZE 78
           #define DS4_REPORT_0x81_SIZE 7
-------- --#define SIXAXIS_REPORT_0xF2_SIZE 18
++++++++ ++#define SIXAXIS_REPORT_0xF2_SIZE 17
++++++++ ++#define SIXAXIS_REPORT_0xF5_SIZE 8
           
 -   - --- static spinlock_t sony_dev_list_lock;
 +   + +++ static DEFINE_SPINLOCK(sony_dev_list_lock);
           static LIST_HEAD(sony_device_list);
           static DEFINE_IDA(sony_device_id_allocator);
           
@@@@@@@@@@@@ -1130,18 -1130,18 -1130,18 -1130,18 -1130,18 -1130,18 -1130,18 -1130,18 -1131,38 -1130,18 -1130,18 +1131,38 @@@@@@@@@@@@ static void sony_input_configured(struc
            */
           static int sixaxis_set_operational_usb(struct hid_device *hdev)
           {
++++++++ ++     const int buf_size =
++++++++ ++             max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE);
++++++++ ++     __u8 *buf;
                int ret;
-------- --     char *buf = kmalloc(18, GFP_KERNEL);
           
++++++++ ++     buf = kmalloc(buf_size, GFP_KERNEL);
                if (!buf)
                        return -ENOMEM;
           
-------- --     ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
-------- --                              HID_REQ_GET_REPORT);
++++++++ ++     ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE,
++++++++ ++                              HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
++++++++ ++     if (ret < 0) {
++++++++ ++             hid_err(hdev, "can't set operational mode: step 1\n");
++++++++ ++             goto out;
++++++++ ++     }
+ +++ +   +
++++++++ ++     /*
++++++++ ++      * Some compatible controllers like the Speedlink Strike FX and
++++++++ ++      * Gasia need another query plus an USB interrupt to get operational.
++++++++ ++      */
++++++++ ++     ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE,
++++++++ ++                              HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
++++++++ ++     if (ret < 0) {
++++++++ ++             hid_err(hdev, "can't set operational mode: step 2\n");
++++++++ ++             goto out;
++++++++ ++     }
 +   + + + 
++++++++ ++     ret = hid_hw_output_report(hdev, buf, 1);
                if (ret < 0)
-------- --             hid_err(hdev, "can't set operational mode\n");
++++++++ ++             hid_err(hdev, "can't set operational mode: step 3\n");
           
++++++++ ++out:
                kfree(buf);
           
                return ret;
@@@@@@@@@@@@ -1944,8 -1944,6 -1944,8 -1944,8 -1944,8 -1944,6 -1944,8 -1944,6 -1965,6 -1944,6 -1944,8 +1965,8 @@@@@@@@@@@@ static int sony_probe(struct hid_devic
                        return -ENOMEM;
                }
           
 +   + +++      spin_lock_init(&sc->lock);
 +   + +++ 
                sc->quirks = quirks;
                hid_set_drvdata(hdev, sc);
                sc->hdev = hdev;
@@@@@@@@@@@@ -2149,8 -2147,8 -2149,8 -2149,8 -2149,8 -2147,8 -2149,8 -2147,8 -2168,8 -2147,8 -2149,8 +2170,8 @@@@@@@@@@@@ static void __exit sony_exit(void
           {
                dbg_hid("Sony:%s\n", __func__);
           
 -   - ---      ida_destroy(&sony_device_id_allocator);
                hid_unregister_driver(&sony_driver);
 +   + +++      ida_destroy(&sony_device_id_allocator);
           }
           module_init(sony_init);
           module_exit(sony_exit);
@@@@@@@@@@@@ -78,13 -78,6 -78,6 -78,6 -78,6 -78,6 -78,6 -78,6 -78,6 -78,6 -78,9 +78,13 @@@@@@@@@@@@ static const struct hid_blacklist 
                { 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_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
 ++++++++++     { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
 ++++++++++     { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
 +++++++++      { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
 +++++++++      { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
 ++++++++++     { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
 ++++++++++     { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL },
 ++++++++++     { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL },
                { 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_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
 ++++++++++     { USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL },
                { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET },
                { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
-- --------     { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
-- --------     { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
-- --------     { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
-- --------     { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
+ +++++++++     { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT },
                { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
                { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS },
diff --combined drivers/input/input-mt.c
@@@@@@@@@@@@ -88,10 -88,10 -88,10 -88,10 -88,10 -88,10 -88,10 -88,10 -88,10 -88,13 -88,10 +88,13 @@@@@@@@@@@@ int input_mt_init_slots(struct input_de
                                goto err_mem;
                }
           
--------- -     /* Mark slots as 'unused' */
+++++++++ +     /* Mark slots as 'inactive' */
                for (i = 0; i < num_slots; i++)
                        input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
           
+++++++++ +     /* Mark slots as 'unused' */
+++++++++ +     mt->frame = 1;
+++++++++ +
                dev->mt = mt;
                return 0;
           err_mem:
@@@@@@@@@@@@ -293,7 -293,7 -293,7 -293,7 -293,7 -293,7 -293,7 -293,7 -293,7 -296,7 -293,7 +296,7 @@@@@@@@@@@@ void input_mt_sync_frame(struct input_d
           }
           EXPORT_SYMBOL(input_mt_sync_frame);
           
--   - ----static int adjust_dual(int *begin, int step, int *end, int eq)
++   + ++++static int adjust_dual(int *begin, int step, int *end, int eq, int mu)
           {
                int f, *p, s, c;
           
                                s = *p;
           
                c = (f + s + 1) / 2;
--   - ----     if (c == 0 || (c > 0 && !eq))
++   + ++++     if (c == 0 || (c > mu && (!eq || mu > 0)))
                        return 0;
--   - ----     if (s < 0)
++   + ++++     /* Improve convergence for positive matrices by penalizing overcovers */
++   + ++++     if (s < 0 && mu <= 0)
                        c *= 2;
           
                for (p = begin; p != end; p += step)
                return (c < s && s <= 0) || (f >= 0 && f < c);
           }
           
--   - ----static void find_reduced_matrix(int *w, int nr, int nc, int nrc)
++   + ++++static void find_reduced_matrix(int *w, int nr, int nc, int nrc, int mu)
           {
                int i, k, sum;
           
                for (k = 0; k < nrc; k++) {
                        for (i = 0; i < nr; i++)
--   - ----                     adjust_dual(w + i, nr, w + i + nrc, nr <= nc);
++   + ++++                     adjust_dual(w + i, nr, w + i + nrc, nr <= nc, mu);
                        sum = 0;
                        for (i = 0; i < nrc; i += nr)
--   - ----                     sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr);
++   + ++++                     sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr, mu);
                        if (!sum)
                                break;
                }
           }
           
           static int input_mt_set_matrix(struct input_mt *mt,
--   - ----                            const struct input_mt_pos *pos, int num_pos)
++   + ++++                            const struct input_mt_pos *pos, int num_pos,
++   + ++++                            int mu)
           {
                const struct input_mt_pos *p;
                struct input_mt_slot *s;
                        y = input_mt_get_value(s, ABS_MT_POSITION_Y);
                        for (p = pos; p != pos + num_pos; p++) {
                                int dx = x - p->x, dy = y - p->y;
--   - ----                     *w++ = dx * dx + dy * dy;
++   + ++++                     *w++ = dx * dx + dy * dy - mu;
                        }
                }
           
@@@@@@@@@@@@ -393,17 -393,17 -395,24 -395,24 -395,24 -393,17 -395,24 -393,17 -393,17 -396,17 -393,17 +398,24 @@@@@@@@@@@@ static void input_mt_set_slots(struct i
            * @slots: the slot assignment to be filled
            * @pos: the position array to match
            * @num_pos: number of positions
++   + ++++ * @dmax: maximum ABS_MT_POSITION displacement (zero for infinite)
            *
            * Performs a best match against the current contacts and returns
            * the slot assignment list. New contacts are assigned to unused
            * slots.
            *
++   + ++++ * The assignments are balanced so that all coordinate displacements are
++   + ++++ * below the euclidian distance dmax. If no such assignment can be found,
++   + ++++ * some contacts are assigned to unused slots.
++   + ++++ *
            * Returns zero on success, or negative error in case of failure.
            */
           int input_mt_assign_slots(struct input_dev *dev, int *slots,
--   - ----                       const struct input_mt_pos *pos, int num_pos)
++   + ++++                       const struct input_mt_pos *pos, int num_pos,
++   + ++++                       int dmax)
           {
                struct input_mt *mt = dev->mt;
++   + ++++     int mu = 2 * dmax * dmax;
                int nrc;
           
                if (!mt || !mt->red)
                if (num_pos < 1)
                        return 0;
           
--   - ----     nrc = input_mt_set_matrix(mt, pos, num_pos);
--   - ----     find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc);
++   + ++++     nrc = input_mt_set_matrix(mt, pos, num_pos, mu);
++   + ++++     find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc, mu);
                input_mt_set_slots(mt, slots, num_pos);
           
                return 0;
@@@@@@@@@@@@ -430,6 -430,6 -439,6 -439,6 -439,6 -430,6 -439,6 -430,6 -430,6 -433,8 -430,6 +442,8 @@@@@@@@@@@@ EXPORT_SYMBOL(input_mt_assign_slots)
            * set the key on the first unused slot and return.
            *
            * If no available slot can be found, -1 is returned.
+++++++++ + * Note that for this function to work properly, input_mt_sync_frame() has
+++++++++ + * to be called at each frame.
            */
           int input_mt_get_slot_by_key(struct input_dev *dev, int key)
           {
                                return s - mt->slots;
           
                for (s = mt->slots; s != mt->slots + mt->num_slots; s++)
--------- -             if (!input_mt_is_active(s)) {
+++++++++ +             if (!input_mt_is_active(s) && !input_mt_is_used(mt, s)) {
                                s->key = key;
                                return s - mt->slots;
                        }
diff --combined include/linux/hid.h
@@@@@@@@@@@@ -159,6 -159,6 -159,6 -159,6 -159,6 -159,6 -159,6 -159,6 -159,6 -159,7 -159,6 +159,7 @@@@@@@@@@@@ struct hid_item 
           #define HID_UP_LED           0x00080000
           #define HID_UP_BUTTON                0x00090000
           #define HID_UP_ORDINAL               0x000a0000
+++++++++ +#define HID_UP_TELEPHONY     0x000b0000
           #define HID_UP_CONSUMER              0x000c0000
           #define HID_UP_DIGITIZER     0x000d0000
           #define HID_UP_PID           0x000f0000
           #define HID_DG_DEVICEINDEX   0x000d0053
           #define HID_DG_CONTACTCOUNT  0x000d0054
           #define HID_DG_CONTACTMAX    0x000d0055
++++++ ++++#define HID_DG_BUTTONTYPE    0x000d0059
           #define HID_DG_BARRELSWITCH2 0x000d005a
           #define HID_DG_TOOLSERIALNUMBER      0x000d005b