Hi!

This (experimental) patch adds support for Wacom PenPartner to the HID
module. I've checked that it doesn't break keyboards and mice. It should
also make other HID digitizers map better into the event interface.

-- 
Vojtech Pavlik
SuSE Labs
diff -urN linux-2.4.0-2-old/drivers/usb/hid-debug.h linux/drivers/usb/hid-debug.h
--- linux-2.4.0-2-old/drivers/usb/hid-debug.h   Fri Feb 11 02:07:26 2000
+++ linux/drivers/usb/hid-debug.h       Sat Mar 18 11:50:05 2000
@@ -105,6 +105,7 @@
     {0, 0x35, "Tap"},
     {0, 0x39, "TabletFunctionKey"},
     {0, 0x3a, "ProgramChangeKey"},
+    {0, 0x3c, "Invert"},
     {0, 0x42, "TipSwitch"},
     {0, 0x43, "SecondaryTipSwitch"},
     {0, 0x44, "BarrelSwitch"},
diff -urN linux-2.4.0-2-old/drivers/usb/hid.c linux/drivers/usb/hid.c
--- linux-2.4.0-2-old/drivers/usb/hid.c Sat Mar 11 01:18:34 2000
+++ linux/drivers/usb/hid.c     Sat Mar 18 13:14:21 2000
@@ -802,6 +802,11 @@
 
                                case 0x30: /* TipPressure */
 
+                                       if (!test_bit(BTN_TOUCH, input->keybit)) {
+                                               device->quirks |= HID_QUIRK_NOTOUCH;
+                                               set_bit(EV_KEY, input->evbit);
+                                               set_bit(BTN_TOUCH, input->keybit);
+                                       }
                                        usage->type = EV_ABS; bit = input->absbit; max 
= ABS_MAX; 
                                        usage->code = ABS_PRESSURE;
                                        clear_bit(usage->code, bit);
@@ -817,10 +822,18 @@
                                        }
                                        break;
 
+                               case 0x3c: /* Invert */
+
+                                       usage->type = EV_KEY; bit = input->keybit; max 
+= KEY_MAX;
+                                       usage->code = BTN_TOOL_RUBBER;
+                                       clear_bit(usage->code, bit);
+                                       break;
+
                                case 0x33: /* Touch */
                                case 0x42: /* TipSwitch */
                                case 0x43: /* TipSwitch2 */
 
+                                       device->quirks &= ~HID_QUIRK_NOTOUCH;
                                        usage->type = EV_KEY; bit = input->keybit; max 
= KEY_MAX;
                                        usage->code = BTN_TOUCH;
                                        clear_bit(usage->code, bit);
@@ -930,7 +943,7 @@
        }
 }
 
-static void hid_process_event(struct input_dev *input, int flags, struct hid_usage 
*usage, __s32 value)
+static void hid_process_event(struct input_dev *input, int *quirks, struct hid_field 
+*field, struct hid_usage *usage, __s32 value)
 {
        hid_dump_input(usage, value);
 
@@ -941,9 +954,30 @@
                return;
        }
 
+       if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
+               *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & 
+~HID_QUIRK_INVERT);
+               return;
+       }
+
+       if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
+               if (value) {
+                       input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? 
+BTN_TOOL_RUBBER : usage->code, 1);
+                       return;
+               }
+               input_event(input, usage->type, usage->code, 0);
+               input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
+               return;
+       }
+
+       if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & 
+HID_QUIRK_NOTOUCH)) { /* Pressure */
+               int a = field->logical_minimum;
+               int b = field->logical_maximum;
+               input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
+       }
+
        input_event(input, usage->type, usage->code, value);
 
-       if ((flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
+       if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
                input_event(input, usage->type, usage->code, 0);
 }
 
@@ -986,19 +1020,21 @@
                        } else {
                                if (value[n] == field->value[n]) continue;
                        }
-                       hid_process_event(&dev->input, field->flags, &field->usage[n], 
value[n]);
+                       hid_process_event(&dev->input, &dev->quirks, field, 
+&field->usage[n], value[n]);
 
                } else {
 
                        if (field->value[n] >= min && field->value[n] <= max           
         /* non-NULL value */
                                && field->usage[field->value[n] - min].hid             
         /* nonzero usage */
                                && search(value, field->value[n], count))
-                                       hid_process_event(&dev->input, field->flags, 
&field->usage[field->value[n] - min], 0);
+                                       hid_process_event(&dev->input, &dev->quirks, 
+field,
+                                               &field->usage[field->value[n] - min], 
+0);
 
                        if (value[n] >= min && value[n] <= max                         
         /* non-NULL value */
                                && field->usage[value[n] - min].hid                    
         /* nonzero usage */
                                && search(field->value, value[n], count))
-                                       hid_process_event(&dev->input, field->flags, 
&field->usage[value[n] - min], 1);
+                                       hid_process_event(&dev->input, &dev->quirks,
+                                               field, &field->usage[value[n] - min], 
+1);
                }
        }
 
diff -urN linux-2.4.0-2-old/drivers/usb/hid.h linux/drivers/usb/hid.h
--- linux-2.4.0-2-old/drivers/usb/hid.h Mon Feb 28 23:21:15 2000
+++ linux/drivers/usb/hid.h     Sat Mar 18 13:11:42 2000
@@ -179,6 +179,13 @@
 #define HID_FEATURE_REPORT     2
 
 /*
+ * HID device quirks.
+ */
+
+#define HID_QUIRK_INVERT       0x01
+#define HID_QUIRK_NOTOUCH      0x02
+
+/*
  * This is the global enviroment of the parser. This information is
  * persistent for main-items. The global enviroment can be saved and
  * restored with PUSH/POP statements.
@@ -285,6 +292,7 @@
        struct urb urb;                                                 /* USB URB 
structure */
        struct urb urbout;                                              /* Output URB 
*/
        struct input_dev input;                                         /* input 
device structure */
+       int quirks;                                                     /* Various 
+nasty tricks the device can pull on us */
 };
 
 #define HID_GLOBAL_STACK_SIZE 4


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to