From: "Paul A. Tessier" <phern...@gmail.com>

adds wireless quirk for interfaces in the wireless kit
corrects led control message when interface is wireless
updates sysfs error message when failing to create group
consolidate and clean up un/registering of interfaces

Signed-off-by: Paul A. Tessier <phern...@gmail.com>
---
 3.7/wacom_sys.c | 111 +++++++++++++++++++++++++++++++++++++-------------------
 3.7/wacom_wac.h |   1 +
 2 files changed, 74 insertions(+), 38 deletions(-)

diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c
index e0311a5..58e8bc6 100644
--- a/3.7/wacom_sys.c
+++ b/3.7/wacom_sys.c
@@ -55,10 +55,11 @@ struct hid_descriptor {
 #define WAC_HID_FEATURE_REPORT 0x03
 #define WAC_MSG_RETRIES                5
 
-#define WAC_CMD_LED_CONTROL    0x20
-#define WAC_CMD_ICON_START     0x21
-#define WAC_CMD_ICON_XFER      0x23
-#define WAC_CMD_RETRIES                10
+#define WAC_CMD_WIRELESS_CONTROL       0x03
+#define WAC_CMD_LED_CONTROL            0x20
+#define WAC_CMD_ICON_START             0x21
+#define WAC_CMD_ICON_XFER              0x23
+#define WAC_CMD_RETRIES                        10
 
 #define DEV_ATTR_RW_PERM (S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH)
 #define DEV_ATTR_RO_PERM (S_IRUSR | S_IRGRP | S_IROTH)
@@ -717,9 +718,19 @@ static void wacom_remove_shared_data(struct wacom_wac 
*wacom)
 static int wacom_led_control(struct wacom *wacom)
 {
        unsigned char *buf;
+       int buf_size;
+       int command;
        int retval;
+       
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_WIRELESS_KIT) {
+               command = WAC_CMD_WIRELESS_CONTROL;
+               buf_size = 13;
+       } else {
+               command = WAC_CMD_LED_CONTROL;
+               buf_size = 9;
+       }
 
-       buf = kzalloc(9, GFP_KERNEL);
+       buf = kzalloc(buf_size, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -733,9 +744,17 @@ static int wacom_led_control(struct wacom *wacom)
                int ring_led = wacom->led.select[0] & 0x03;
                int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03;
                int crop_lum = (((wacom->led.crop_lum & 0x60) >> 5) - 1) & 0x03;
+               int bits = (crop_lum << 4) | (ring_lum << 2) | (ring_led);
 
-               buf[0] = WAC_CMD_LED_CONTROL;
-               buf[1] = (crop_lum << 4) | (ring_lum << 2) | (ring_led);
+               if (wacom->wacom_wac.features.quirks & 
WACOM_QUIRK_WIRELESS_KIT) {
+                       buf[3] = 0x04;
+                       buf[4] = 0x40 | bits;
+               } else {
+                       buf[1] = bits;
+                       
+                       if (wacom->wacom_wac.features.type >= INTUOSPS)
+                               buf[2] = ring_lum;
+               }
        }
        else {
                int led = wacom->led.select[0] | 0x4;
@@ -744,15 +763,15 @@ static int wacom_led_control(struct wacom *wacom)
                    wacom->wacom_wac.features.type == WACOM_24HD)
                        led |= (wacom->led.select[1] << 4) | 0x40;
 
-               buf[0] = WAC_CMD_LED_CONTROL;
                buf[1] = led;
                buf[2] = wacom->led.llv;
                buf[3] = wacom->led.hlv;
                buf[4] = wacom->led.img_lum;
        }
 
-       retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL,
-                                 buf, 9, WAC_CMD_RETRIES);
+       buf[0] = command;
+       retval = wacom_set_report(wacom->intf, 0x03, command, buf, buf_size,
+                                 WAC_CMD_RETRIES);
        kfree(buf);
 
        return retval;
@@ -1019,7 +1038,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
 
        if (error) {
                dev_err(&wacom->intf->dev,
-                       "cannot create sysfs group err: %d\n", error);
+                       "cannot create 'wacom_led' sysfs group: err %d\n", 
error);
                return error;
        }
        wacom_led_control(wacom);
@@ -1151,6 +1170,37 @@ fail1:
        return error;
 }
 
+static void wacom_unregister(struct wacom *wacom)
+{
+       struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+       
+       if (wacom_wac->input) {
+               input_unregister_device(wacom_wac->input);
+               wacom_destroy_leds(wacom);
+       }
+
+       wacom_wac->input = NULL;
+}
+
+static int wacom_register(struct wacom *wacom)
+{
+       int error;
+       
+       error = wacom_initialize_leds(wacom);
+       if (error)
+               goto fail1;
+
+       error = wacom_register_input(wacom);
+       if (error)
+               goto fail2;
+
+       return 0;
+
+fail2: wacom_destroy_leds(wacom);
+fail1:
+       return error;
+}
+
 static void wacom_wireless_work(struct work_struct *work)
 {
        struct wacom *wacom = container_of(work, struct wacom, work);
@@ -1170,16 +1220,12 @@ static void wacom_wireless_work(struct work_struct 
*work)
        /* Stylus interface */
        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;
+       wacom_unregister(wacom1);
 
        /* Touch interface */
        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;
+       wacom_unregister(wacom2);
 
        if (wacom_wac->pid == 0) {
                dev_info(&wacom->intf->dev, "wireless tablet disconnected\n");
@@ -1211,7 +1257,8 @@ static void wacom_wireless_work(struct work_struct *work)
                         wacom_wac1->features.name);
                wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max;
                wacom_wac1->shared->type = wacom_wac1->features.type;
-               error = wacom_register_input(wacom1);
+               wacom_wac1->features.quirks |= WACOM_QUIRK_WIRELESS_KIT;
+               error = wacom_register(wacom1);
                if (error)
                        goto fail;
 
@@ -1229,7 +1276,8 @@ static void wacom_wireless_work(struct work_struct *work)
                        else
                                snprintf(wacom_wac2->name, WACOM_NAME_MAX,
                                         "%s (WL) 
Pad",wacom_wac2->features.name);
-                       error = wacom_register_input(wacom2);
+                       wacom_wac2->features.quirks |= WACOM_QUIRK_WIRELESS_KIT;
+                       error = wacom_register(wacom2);
                        if (error)
                                goto fail;
 
@@ -1246,15 +1294,8 @@ static void wacom_wireless_work(struct work_struct *work)
        return;
 
 fail:
-       if (wacom_wac2->input) {
-               input_unregister_device(wacom_wac2->input);
-               wacom_wac2->input = NULL;
-       }
-
-       if (wacom_wac1->input) {
-               input_unregister_device(wacom_wac1->input);
-               wacom_wac1->input = NULL;
-       }
+       wacom_unregister(wacom2);
+       wacom_unregister(wacom1);
        return;
 }
 
@@ -1389,14 +1430,10 @@ static int wacom_probe(struct usb_interface *intf, 
const struct usb_device_id *i
        wacom->irq->transfer_dma = wacom->data_dma;
        wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       error = wacom_initialize_leds(wacom);
-       if (error)
-               goto fail4;
-
        if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
-               error = wacom_register_input(wacom);
+               error = wacom_register(wacom);
                if (error)
-                       goto fail5;
+                       goto fail4;
        }
 
        /* Note that if query fails it is not a hard failure */
@@ -1418,7 +1455,7 @@ static int wacom_probe(struct usb_interface *intf, const 
struct usb_device_id *i
 
        return 0;
 
- fail5: wacom_destroy_leds(wacom);
+ fail5: wacom_unregister(wacom);
  fail4:        wacom_remove_shared_data(wacom_wac);
  fail3:        usb_free_urb(wacom->irq);
  fail2:        usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, 
wacom->data_dma);
@@ -1434,10 +1471,8 @@ static void wacom_disconnect(struct usb_interface *intf)
 
        usb_kill_urb(wacom->irq);
        cancel_work_sync(&wacom->work);
-       if (wacom->wacom_wac.input)
-               input_unregister_device(wacom->wacom_wac.input);
+       wacom_unregister(wacom);
        wacom_destroy_battery(wacom);
-       wacom_destroy_leds(wacom);
        usb_free_urb(wacom->irq);
        usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
                        wacom->wacom_wac.data, wacom->data_dma);
diff --git a/3.7/wacom_wac.h b/3.7/wacom_wac.h
index f69c0eb..2ec64de 100644
--- a/3.7/wacom_wac.h
+++ b/3.7/wacom_wac.h
@@ -65,6 +65,7 @@
 #define WACOM_QUIRK_BBTOUCH_LOWRES     0x0002
 #define WACOM_QUIRK_NO_INPUT           0x0004
 #define WACOM_QUIRK_MONITOR            0x0008
+#define WACOM_QUIRK_WIRELESS_KIT       0x0016
 
 enum {
        PENPARTNER = 0,
-- 
1.8.3.2


------------------------------------------------------------------------------
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to