Merge commit 'v3.5-rc5' into next
[linux-2.6-block.git] / drivers / input / tablet / wacom_sys.c
index cad5602d3ce45a525ca70d9cc1cf7f766348c24e..9a854e2d15dcbdecd985bb6e43c40550f2dd9604 100644 (file)
@@ -443,8 +443,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
        /* ask to report Wacom data */
        if (features->device_type == BTN_TOOL_FINGER) {
                /* if it is an MT Tablet PC touch */
-               if (features->type == TABLETPC2FG ||
-                   features->type == MTSCREEN) {
+               if (features->type > TABLETPC) {
                        do {
                                rep_data[0] = 3;
                                rep_data[1] = 4;
@@ -463,7 +462,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
                        } while ((error < 0 || rep_data[1] != 4) &&
                                 limit++ < WAC_MSG_RETRIES);
                }
-       } else if (features->type != TABLETPC &&
+       } else if (features->type <= BAMBOO_PT &&
                   features->type != WIRELESS &&
                   features->device_type == BTN_TOOL_PEN) {
                do {
@@ -507,16 +506,13 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
                if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
                        features->device_type = 0;
                } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) {
-                       features->device_type = BTN_TOOL_DOUBLETAP;
+                       features->device_type = BTN_TOOL_FINGER;
                        features->pktlen = WACOM_PKGLEN_BBTOUCH3;
                }
        }
 
        /* only devices that support touch need to retrieve the info */
-       if (features->type != TABLETPC &&
-           features->type != TABLETPC2FG &&
-           features->type != BAMBOO_PT &&
-           features->type != MTSCREEN) {
+       if (features->type < BAMBOO_PT) {
                goto out;
        }
 
@@ -858,6 +854,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
 
        /* Initialize default values */
        switch (wacom->wacom_wac.features.type) {
+       case INTUOS4S:
        case INTUOS4:
        case INTUOS4L:
                wacom->led.select[0] = 0;
@@ -911,6 +908,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
 static void wacom_destroy_leds(struct wacom *wacom)
 {
        switch (wacom->wacom_wac.features.type) {
+       case INTUOS4S:
        case INTUOS4:
        case INTUOS4L:
                sysfs_remove_group(&wacom->intf->dev.kobj,
@@ -970,6 +968,10 @@ static int wacom_initialize_battery(struct wacom *wacom)
 
                error = power_supply_register(&wacom->usbdev->dev,
                                              &wacom->battery);
+
+               if (!error)
+                       power_supply_powers(&wacom->battery,
+                                           &wacom->usbdev->dev);
        }
 
        return error;
@@ -977,8 +979,11 @@ static int wacom_initialize_battery(struct wacom *wacom)
 
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR)
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR &&
+           wacom->battery.dev) {
                power_supply_unregister(&wacom->battery);
+               wacom->battery.dev = NULL;
+       }
 }
 
 static int wacom_register_input(struct wacom *wacom)
@@ -1025,23 +1030,30 @@ static void wacom_wireless_work(struct work_struct *work)
        struct wacom *wacom = container_of(work, struct wacom, work);
        struct usb_device *usbdev = wacom->usbdev;
        struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+       struct wacom *wacom1, *wacom2;
+       struct wacom_wac *wacom_wac1, *wacom_wac2;
+       int error;
 
        /*
         * Regardless if this is a disconnect or a new tablet,
-        * remove any existing input devices.
+        * remove any existing input and battery devices.
         */
 
+       wacom_destroy_battery(wacom);
+
        /* Stylus interface */
-       wacom = usb_get_intfdata(usbdev->config->interface[1]);
-       if (wacom->wacom_wac.input)
-               input_unregister_device(wacom->wacom_wac.input);
-       wacom->wacom_wac.input = NULL;
+       wacom1 = usb_get_intfdata(usbdev->config->interface[1]);
+       wacom_wac1 = &(wacom1->wacom_wac);
+       if (wacom_wac1->input)
+               input_unregister_device(wacom_wac1->input);
+       wacom_wac1->input = NULL;
 
        /* Touch interface */
-       wacom = usb_get_intfdata(usbdev->config->interface[2]);
-       if (wacom->wacom_wac.input)
-               input_unregister_device(wacom->wacom_wac.input);
-       wacom->wacom_wac.input = NULL;
+       wacom2 = usb_get_intfdata(usbdev->config->interface[2]);
+       wacom_wac2 = &(wacom2->wacom_wac);
+       if (wacom_wac2->input)
+               input_unregister_device(wacom_wac2->input);
+       wacom_wac2->input = NULL;
 
        if (wacom_wac->pid == 0) {
                dev_info(&wacom->intf->dev, "wireless tablet disconnected\n");
@@ -1066,24 +1078,39 @@ static void wacom_wireless_work(struct work_struct *work)
                }
 
                /* Stylus interface */
-               wacom = usb_get_intfdata(usbdev->config->interface[1]);
-               wacom_wac = &wacom->wacom_wac;
-               wacom_wac->features =
+               wacom_wac1->features =
                        *((struct wacom_features *)id->driver_info);
-               wacom_wac->features.device_type = BTN_TOOL_PEN;
-               wacom_register_input(wacom);
+               wacom_wac1->features.device_type = BTN_TOOL_PEN;
+               error = wacom_register_input(wacom1);
+               if (error)
+                       goto fail1;
 
                /* Touch interface */
-               wacom = usb_get_intfdata(usbdev->config->interface[2]);
-               wacom_wac = &wacom->wacom_wac;
-               wacom_wac->features =
+               wacom_wac2->features =
                        *((struct wacom_features *)id->driver_info);
-               wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
-               wacom_wac->features.device_type = BTN_TOOL_FINGER;
-               wacom_set_phy_from_res(&wacom_wac->features);
-               wacom_wac->features.x_max = wacom_wac->features.y_max = 4096;
-               wacom_register_input(wacom);
+               wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+               wacom_wac2->features.device_type = BTN_TOOL_FINGER;
+               wacom_set_phy_from_res(&wacom_wac2->features);
+               wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
+               error = wacom_register_input(wacom2);
+               if (error)
+                       goto fail2;
+
+               error = wacom_initialize_battery(wacom);
+               if (error)
+                       goto fail3;
        }
+
+       return;
+
+fail3:
+       input_unregister_device(wacom_wac2->input);
+       wacom_wac2->input = NULL;
+fail2:
+       input_unregister_device(wacom_wac1->input);
+       wacom_wac1->input = NULL;
+fail1:
+       return;
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1147,10 +1174,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
                        features->device_type = BTN_TOOL_FINGER;
                        features->pktlen = WACOM_PKGLEN_BBTOUCH3;
 
-                       features->x_phy =
-                               (features->x_max * 100) / features->x_resolution;
-                       features->y_phy =
-                               (features->y_max * 100) / features->y_resolution;
+                       wacom_set_phy_from_res(features);
 
                        features->x_max = 4096;
                        features->y_max = 4096;
@@ -1186,14 +1210,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        if (error)
                goto fail4;
 
-       error = wacom_initialize_battery(wacom);
-       if (error)
-               goto fail5;
-
        if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
                error = wacom_register_input(wacom);
                if (error)
-                       goto fail6;
+                       goto fail5;
        }
 
        /* Note that if query fails it is not a hard failure */
@@ -1208,7 +1228,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        return 0;
 
- fail6: wacom_destroy_battery(wacom);
  fail5: wacom_destroy_leds(wacom);
  fail4:        wacom_remove_shared_data(wacom_wac);
  fail3:        usb_free_urb(wacom->irq);