HID: wacom: Consult the application usage when determining field type
[firefly-linux-kernel-4.4.55.git] / drivers / hid / wacom_wac.c
index 586b2405b0d43836fc2653af5b39904c03802097..1468f008bfbdcd718f5ac8dd626fa68b39a314c2 100644 (file)
@@ -600,8 +600,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom)
                }
                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);
@@ -612,8 +612,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom)
                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 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
                                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);
@@ -1484,9 +1484,11 @@ static void wacom_wac_finger_report(struct hid_device *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 +1683,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
            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 +1778,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
                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);
@@ -1926,8 +1931,10 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
        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)
@@ -1947,6 +1954,7 @@ 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 +2037,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev,
        }
 }
 
-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;
@@ -2047,9 +2055,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
 
        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 */
 
@@ -2092,6 +2097,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
 
        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 */
 
@@ -2106,6 +2112,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
        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);
 
@@ -2114,6 +2121,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
 
        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;
@@ -2122,6 +2130,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
        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:
@@ -2144,6 +2153,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                                              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) {
@@ -2162,6 +2172,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
        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);
@@ -2246,6 +2257,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                                __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);
@@ -2261,6 +2275,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
 
        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 +2318,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
 
        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;
 
@@ -2402,7 +2415,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
        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);
@@ -2446,8 +2459,10 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
        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);
 
@@ -2460,7 +2475,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
 
        default:
                /* no pad supported */
-               return 1;
+               return -ENODEV;
        }
        return 0;
 }
@@ -2878,6 +2893,10 @@ 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,6 +3041,7 @@ 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(0x4001) },
        { USB_DEVICE_WACOM(0x4004) },
        { USB_DEVICE_WACOM(0x5000) },