ext4: update PF_MEMALLOC handling in ext4_write_inode()
[pandora-kernel.git] / drivers / hid / hid-microsoft.c
index 404a3a8..6fd5817 100644 (file)
@@ -62,9 +62,48 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
 {
        struct input_dev *input = hi->input;
 
+       if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
+               switch (usage->hid & HID_USAGE) {
+               /*
+                * Microsoft uses these 2 reserved usage ids for 2 keys on
+                * the MS office kb labelled "Office Home" and "Task Pane".
+                */
+               case 0x29d:
+                       ms_map_key_clear(KEY_PROG1);
+                       return 1;
+               case 0x29e:
+                       ms_map_key_clear(KEY_PROG2);
+                       return 1;
+               }
+               return 0;
+       }
+
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+               return 0;
+
        switch (usage->hid & HID_USAGE) {
        case 0xfd06: ms_map_key_clear(KEY_CHAT);        break;
        case 0xfd07: ms_map_key_clear(KEY_PHONE);       break;
+       case 0xff00:
+               /* Special keypad keys */
+               ms_map_key_clear(KEY_KPEQUAL);
+               set_bit(KEY_KPLEFTPAREN, input->keybit);
+               set_bit(KEY_KPRIGHTPAREN, input->keybit);
+               break;
+       case 0xff01:
+               /* Scroll wheel */
+               hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
+               break;
+       case 0xff02:
+               /*
+                * This byte contains a copy of the modifier keys byte of a
+                * standard hid keyboard report, as send by interface 0
+                * (this usage is found on interface 1).
+                *
+                * This byte only gets send when another key in the same report
+                * changes state, and as such is useless, ignore it.
+                */
+               return -1;
        case 0xff05:
                set_bit(EV_REP, input->evbit);
                ms_map_key_clear(KEY_F13);
@@ -83,6 +122,9 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
 static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
                unsigned long **bit, int *max)
 {
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+               return 0;
+
        set_bit(EV_REP, hi->input->evbit);
        switch (usage->hid & HID_USAGE) {
        case 0xfd08: ms_map_key_clear(KEY_FORWARD);     break;
@@ -102,9 +144,6 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 {
        unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
 
-       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
-               return 0;
-
        if (quirks & MS_ERGONOMY) {
                int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
                if (ret)
@@ -134,14 +173,39 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
                struct hid_usage *usage, __s32 value)
 {
        unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+       struct input_dev *input;
 
        if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
                        !usage->type)
                return 0;
 
+       input = field->hidinput->input;
+
        /* Handling MS keyboards special buttons */
+       if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
+               /* Special keypad keys */
+               input_report_key(input, KEY_KPEQUAL, value & 0x01);
+               input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
+               input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
+               return 1;
+       }
+
+       if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
+               /* Scroll wheel */
+               int step = ((value & 0x60) >> 5) + 1;
+
+               switch (value & 0x1f) {
+               case 0x01:
+                       input_report_rel(input, REL_WHEEL, step);
+                       break;
+               case 0x1f:
+                       input_report_rel(input, REL_WHEEL, -step);
+                       break;
+               }
+               return 1;
+       }
+
        if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
-               struct input_dev *input = field->hidinput->input;
                static unsigned int last_key = 0;
                unsigned int key = 0;
                switch (value) {
@@ -194,6 +258,8 @@ err_free:
 static const struct hid_device_id ms_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
                .driver_data = MS_HIDINPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
+               .driver_data = MS_ERGONOMY },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
                .driver_data = MS_ERGONOMY },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),