]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/hid/wacom_sys.c
Merge branches 'for-4.4/upstream-fixes', 'for-4.5/async-suspend', 'for-4.5/container...
[mirror_ubuntu-artful-kernel.git] / drivers / hid / wacom_sys.c
index 9a4912c1828dad3109b9473305670c79fc20d022..5cb21dd91094f712038f56fcfc03ea5a2fa3e1c7 100644 (file)
@@ -211,7 +211,7 @@ static void wacom_usage_mapping(struct hid_device *hdev,
         * Bamboo models do not support HID_DG_CONTACTMAX.
         * And, Bamboo Pen only descriptor contains touch.
         */
-       if (features->type != BAMBOO_PT) {
+       if (features->type > BAMBOO_PT) {
                /* ISDv4 touch devices at least supports one touch point */
                if (finger && !features->touch_max)
                        features->touch_max = 1;
@@ -222,7 +222,8 @@ static void wacom_usage_mapping(struct hid_device *hdev,
                features->x_max = field->logical_maximum;
                if (finger) {
                        features->x_phy = field->physical_maximum;
-                       if (features->type != BAMBOO_PT) {
+                       if ((features->type != BAMBOO_PT) &&
+                           (features->type != BAMBOO_TOUCH)) {
                                features->unit = field->unit;
                                features->unitExpo = field->unit_exponent;
                        }
@@ -232,7 +233,8 @@ static void wacom_usage_mapping(struct hid_device *hdev,
                features->y_max = field->logical_maximum;
                if (finger) {
                        features->y_phy = field->physical_maximum;
-                       if (features->type != BAMBOO_PT) {
+                       if ((features->type != BAMBOO_PT) &&
+                           (features->type != BAMBOO_TOUCH)) {
                                features->unit = field->unit;
                                features->unitExpo = field->unit_exponent;
                        }
@@ -420,7 +422,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev,
                        /* MT Tablet PC touch */
                        return wacom_set_device_mode(hdev, 3, 4, 4);
                }
-               else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) {
+               else if (features->type == WACOM_24HDT) {
                        return wacom_set_device_mode(hdev, 18, 3, 2);
                }
                else if (features->type == WACOM_27QHDT) {
@@ -430,7 +432,7 @@ static int wacom_query_tablet_data(struct hid_device *hdev,
                        return wacom_set_device_mode(hdev, 2, 2, 2);
                }
        } else if (features->device_type & WACOM_DEVICETYPE_PEN) {
-               if (features->type <= BAMBOO_PT && features->type != WIRELESS) {
+               if (features->type <= BAMBOO_PT) {
                        return wacom_set_device_mode(hdev, 2, 2, 2);
                }
        }
@@ -684,7 +686,7 @@ out:
 static ssize_t wacom_led_select_store(struct device *dev, int set_id,
                                      const char *buf, size_t count)
 {
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
        unsigned int id;
        int err;
@@ -712,7 +714,7 @@ static ssize_t wacom_led##SET_ID##_select_store(struct device *dev, \
 static ssize_t wacom_led##SET_ID##_select_show(struct device *dev,     \
        struct device_attribute *attr, char *buf)                       \
 {                                                                      \
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
+       struct hid_device *hdev = to_hid_device(dev);\
        struct wacom *wacom = hid_get_drvdata(hdev);                    \
        return scnprintf(buf, PAGE_SIZE, "%d\n",                        \
                         wacom->led.select[SET_ID]);                    \
@@ -748,7 +750,7 @@ static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest,
 static ssize_t wacom_##name##_luminance_store(struct device *dev,      \
        struct device_attribute *attr, const char *buf, size_t count)   \
 {                                                                      \
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
+       struct hid_device *hdev = to_hid_device(dev);\
        struct wacom *wacom = hid_get_drvdata(hdev);                    \
                                                                        \
        return wacom_luminance_store(wacom, &wacom->led.field,          \
@@ -771,7 +773,7 @@ DEVICE_LUMINANCE_ATTR(buttons, img_lum);
 static ssize_t wacom_button_image_store(struct device *dev, int button_id,
                                        const char *buf, size_t count)
 {
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
        int err;
        unsigned len;
@@ -1095,7 +1097,7 @@ static ssize_t wacom_show_speed(struct device *dev,
                                struct device_attribute
                                *attr, char *buf)
 {
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
 
        return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
@@ -1105,7 +1107,7 @@ static ssize_t wacom_store_speed(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
        u8 new_speed;
 
@@ -1128,8 +1130,8 @@ static ssize_t wacom_show_remote_mode(struct kobject *kobj,
                                      struct kobj_attribute *kattr,
                                      char *buf, int index)
 {
-       struct device *dev = container_of(kobj->parent, struct device, kobj);
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct device *dev = kobj_to_dev(kobj->parent);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
        u8 mode;
 
@@ -1239,8 +1241,8 @@ static ssize_t wacom_store_unpair_remote(struct kobject *kobj,
                                         const char *buf, size_t count)
 {
        unsigned char selector = 0;
-       struct device *dev = container_of(kobj->parent, struct device, kobj);
-       struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+       struct device *dev = kobj_to_dev(kobj->parent);
+       struct hid_device *hdev = to_hid_device(dev);
        struct wacom *wacom = hid_get_drvdata(hdev);
        int err;
 
@@ -1351,8 +1353,7 @@ static void wacom_clean_inputs(struct wacom *wacom)
                else
                        input_free_device(wacom->wacom_wac.pad_input);
        }
-       if (wacom->remote_dir)
-               kobject_put(wacom->remote_dir);
+       kobject_put(wacom->remote_dir);
        wacom->wacom_wac.pen_input = NULL;
        wacom->wacom_wac.touch_input = NULL;
        wacom->wacom_wac.pad_input = NULL;
@@ -1547,15 +1548,16 @@ static void wacom_wireless_work(struct work_struct *work)
                wacom_wac1->features =
                        *((struct wacom_features *)id->driver_data);
                wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PEN;
-               if (wacom_wac1->features.type != INTUOSHT &&
-                   wacom_wac1->features.type != BAMBOO_PT)
-                       wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD;
                wacom_set_default_phy(&wacom_wac1->features);
                wacom_calculate_res(&wacom_wac1->features);
                snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen",
                         wacom_wac1->features.name);
-               snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
-                        wacom_wac1->features.name);
+               if (wacom_wac1->features.type < BAMBOO_PEN ||
+                   wacom_wac1->features.type > BAMBOO_PT) {
+                       snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
+                                wacom_wac1->features.name);
+                       wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD;
+               }
                wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max;
                wacom_wac1->shared->type = wacom_wac1->features.type;
                wacom_wac1->pid = wacom_wac->pid;
@@ -1566,7 +1568,8 @@ static void wacom_wireless_work(struct work_struct *work)
 
                /* Touch interface */
                if (wacom_wac1->features.touch_max ||
-                   wacom_wac1->features.type == INTUOSHT) {
+                   (wacom_wac1->features.type >= INTUOSHT &&
+                   wacom_wac1->features.type <= BAMBOO_PT)) {
                        wacom_wac2->features =
                                *((struct wacom_features *)id->driver_data);
                        wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
@@ -1575,20 +1578,22 @@ static void wacom_wireless_work(struct work_struct *work)
                        wacom_calculate_res(&wacom_wac2->features);
                        snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX,
                                 "%s (WL) Finger",wacom_wac2->features.name);
-                       snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
-                                "%s (WL) Pad",wacom_wac2->features.name);
                        if (wacom_wac1->features.touch_max)
                                wacom_wac2->features.device_type |= WACOM_DEVICETYPE_TOUCH;
-                       if (wacom_wac1->features.type == INTUOSHT ||
-                           wacom_wac1->features.type == BAMBOO_PT)
+                       if (wacom_wac1->features.type >= INTUOSHT &&
+                           wacom_wac1->features.type <= BAMBOO_PT) {
+                               snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
+                                        "%s (WL) Pad",wacom_wac2->features.name);
                                wacom_wac2->features.device_type |= WACOM_DEVICETYPE_PAD;
+                       }
                        wacom_wac2->pid = wacom_wac->pid;
                        error = wacom_allocate_inputs(wacom2) ||
                                wacom_register_inputs(wacom2);
                        if (error)
                                goto fail;
 
-                       if (wacom_wac1->features.type == INTUOSHT &&
+                       if ((wacom_wac1->features.type == INTUOSHT ||
+                           wacom_wac1->features.type == INTUOSHT2) &&
                            wacom_wac1->features.touch_max)
                                wacom_wac->shared->touch_input = wacom_wac2->touch_input;
                }
@@ -1812,11 +1817,27 @@ static int wacom_probe(struct hid_device *hdev,
        /* Note that if query fails it is not a hard failure */
        wacom_query_tablet_data(hdev, features);
 
+       /* touch only Bamboo doesn't support pen */
+       if ((features->type == BAMBOO_TOUCH) &&
+           (features->device_type & WACOM_DEVICETYPE_PEN)) {
+               error = -ENODEV;
+               goto fail_hw_start;
+       }
+
+       /* pen only Bamboo neither support touch nor pad */
+       if ((features->type == BAMBOO_PEN) &&
+           ((features->device_type & WACOM_DEVICETYPE_TOUCH) ||
+           (features->device_type & WACOM_DEVICETYPE_PAD))) {
+               error = -ENODEV;
+               goto fail_hw_start;
+       }
+
        if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
                error = hid_hw_open(hdev);
 
-       if (wacom_wac->features.type == INTUOSHT && 
-           wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) {
+       if ((wacom_wac->features.type == INTUOSHT ||
+           wacom_wac->features.type == INTUOSHT2) &&
+           (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)) {
                        wacom_wac->shared->touch_input = wacom_wac->touch_input;
        }