Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / drivers / usb / input / hid-input.c
index 028e1ad..3a7e5fb 100644 (file)
@@ -65,11 +65,9 @@ static const struct {
 #define map_rel(c)     do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
 #define map_key(c)     do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
 #define map_led(c)     do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
-#define map_ff(c)      do { usage->code = c; usage->type = EV_FF;  bit = input->ffbit;  max =  FF_MAX; } while (0)
 
 #define map_abs_clear(c)       do { map_abs(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)       do { map_key(c); clear_bit(c, bit); } while (0)
-#define map_ff_effect(c)       do { set_bit(c, input->ffbit); } while (0)
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 
@@ -123,6 +121,12 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = {
        { }
 };
 
+static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+       { KEY_GRAVE,    KEY_102ND },
+       { KEY_102ND,    KEY_GRAVE },
+       { }
+};
+
 static int usbhid_pb_fnmode = 1;
 module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
 MODULE_PARM_DESC(pb_fnmode,
@@ -197,6 +201,14 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
                }
        }
 
+       if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+               trans = find_translation(powerbook_iso_keyboard, usage->code);
+               if (trans) {
+                       input_event(input, usage->type, trans->to, value);
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
@@ -212,6 +224,9 @@ static void hidinput_pb_setup(struct input_dev *input)
 
        for (trans = powerbook_numlock_keys; trans->from; trans++)
                set_bit(trans->to, input->keybit);
+
+       for (trans = powerbook_iso_keyboard; trans->from; trans++)
+               set_bit(trans->to, input->keybit);
 }
 #else
 static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
@@ -525,23 +540,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
                case HID_UP_PID:
 
-                       set_bit(EV_FF, input->evbit);
                        switch(usage->hid & HID_USAGE) {
-                               case 0x26: map_ff_effect(FF_CONSTANT);  goto ignore;
-                               case 0x27: map_ff_effect(FF_RAMP);      goto ignore;
-                               case 0x28: map_ff_effect(FF_CUSTOM);    goto ignore;
-                               case 0x30: map_ff_effect(FF_SQUARE);    map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x31: map_ff_effect(FF_SINE);      map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x32: map_ff_effect(FF_TRIANGLE);  map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x33: map_ff_effect(FF_SAW_UP);    map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x34: map_ff_effect(FF_SAW_DOWN);  map_ff_effect(FF_PERIODIC); goto ignore;
-                               case 0x40: map_ff_effect(FF_SPRING);    goto ignore;
-                               case 0x41: map_ff_effect(FF_DAMPER);    goto ignore;
-                               case 0x42: map_ff_effect(FF_INERTIA);   goto ignore;
-                               case 0x43: map_ff_effect(FF_FRICTION);  goto ignore;
-                               case 0x7e: map_ff(FF_GAIN);             break;
-                               case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
-                               case 0x98: map_ff(FF_AUTOCENTER);       break;
                                case 0xa4: map_key_clear(BTN_DEAD);     break;
                                default: goto ignore;
                        }
@@ -582,6 +581,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
                goto ignore;
 
+       if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
+           usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
+               field->flags &= ~HID_MAIN_ITEM_RELATIVE;
+
        set_bit(usage->type, input->evbit);
 
        while (usage->code <= max && test_and_set_bit(usage->code, bit))
@@ -607,7 +610,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
        }
 
-       if (usage->hat_min < usage->hat_max || usage->hat_dir) {
+       if (usage->type == EV_ABS &&
+           (usage->hat_min < usage->hat_max || usage->hat_dir)) {
                int i;
                for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
                        input_set_abs_params(input, i, -1, 1, 0, 0);
@@ -630,7 +634,7 @@ ignore:
        return;
 }
 
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
+void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
 {
        struct input_dev *input;
        int *quirks = &hid->quirks;
@@ -640,8 +644,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
        input = field->hidinput->input;
 
-       input_regs(input, regs);
-
        if (!usage->type)
                return;
 
@@ -697,8 +699,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
        }
 
        if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
-               input->ff_effects_max = value;
-               dbg("Maximum Effects - %d",input->ff_effects_max);
+               dbg("Maximum Effects - %d",value);
                return;
        }
 
@@ -747,7 +748,7 @@ static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsign
        int offset;
 
        if (type == EV_FF)
-               return hid_ff_event(hid, dev, type, code, value);
+               return input_ff_event(dev, type, code, value);
 
        if (type != EV_LED)
                return -1;