more trivial signedness fixes in drivers
[safe/jmp/linux-2.6] / drivers / hid / hid-input.c
index 00f3260..dd332f2 100644 (file)
@@ -88,7 +88,7 @@ static const struct {
 
 /* hardware needing special handling due to colliding MSVENDOR page usages */
 #define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418)
-#define IS_MS_NEK4K(x) (x->vendor == 0x045e && x->product == 0x00db)
+#define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
 
@@ -299,7 +299,7 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode,
 {
        struct hid_device *hid = dev->private;
        struct hid_usage *usage;
-       
+
        usage = hidinput_find_key(hid, scancode, 0);
        if (usage) {
                *keycode = usage->code;
@@ -314,15 +314,15 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
        struct hid_device *hid = dev->private;
        struct hid_usage *usage;
        int old_keycode;
-       
+
        if (keycode < 0 || keycode > KEY_MAX)
                return -EINVAL;
-       
+
        usage = hidinput_find_key(hid, scancode, 0);
        if (usage) {
                old_keycode = usage->code;
                usage->code = keycode;
-               
+
                clear_bit(old_keycode, dev->keybit);
                set_bit(usage->code, dev->keybit);
                dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
@@ -330,10 +330,10 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
                 * by another key */
                if (hidinput_find_key (hid, 0, old_keycode))
                        set_bit(old_keycode, dev->keybit);
-               
+
                return 0;
        }
-       
+
        return -EINVAL;
 }
 
@@ -355,6 +355,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
        if (field->flags & HID_MAIN_ITEM_CONSTANT)
                goto ignore;
 
+       /* only LED usages are supported in output fields */
+       if (field->report_type == HID_OUTPUT_REPORT &&
+                       (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
+               dbg_hid_line(" [non-LED output field] ");
+               goto ignore;
+       }
+
        switch (usage->hid & HID_USAGE_PAGE) {
 
                case HID_UP_UNDEFINED:
@@ -599,6 +606,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x0f6: map_key_clear(KEY_NEXT);            break;
                                case 0x0fa: map_key_clear(KEY_BACK);            break;
 
+                               case 0x182: map_key_clear(KEY_BOOKMARKS);       break;
                                case 0x183: map_key_clear(KEY_CONFIG);          break;
                                case 0x184: map_key_clear(KEY_WORDPROCESSOR);   break;
                                case 0x185: map_key_clear(KEY_EDITOR);          break;
@@ -615,10 +623,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x192: map_key_clear(KEY_CALC);            break;
                                case 0x194: map_key_clear(KEY_FILE);            break;
                                case 0x196: map_key_clear(KEY_WWW);             break;
+                               case 0x19c: map_key_clear(KEY_LOGOFF);          break;
                                case 0x19e: map_key_clear(KEY_COFFEE);          break;
                                case 0x1a6: map_key_clear(KEY_HELP);            break;
                                case 0x1a7: map_key_clear(KEY_DOCUMENTS);       break;
                                case 0x1ab: map_key_clear(KEY_SPELLCHECK);      break;
+                               case 0x1b6: map_key_clear(KEY_MEDIA);           break;
+                               case 0x1b7: map_key_clear(KEY_SOUND);           break;
                                case 0x1bc: map_key_clear(KEY_MESSENGER);       break;
                                case 0x1bd: map_key_clear(KEY_INFO);            break;
                                case 0x201: map_key_clear(KEY_NEW);             break;
@@ -751,16 +762,22 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                }
 
                        /* Microsoft Natural Ergonomic Keyboard 4000 */
-                       } else if (IS_MS_NEK4K(device)) {
+                       } else if (IS_MS_KB(device)) {
                                switch(usage->hid & HID_USAGE) {
+                                       case 0xfd06:
+                                               map_key_clear(KEY_CHAT);
+                                               break;
+                                       case 0xfd07:
+                                               map_key_clear(KEY_PHONE);
+                                               break;
                                        case 0xff05:
                                                set_bit(EV_REP, input->evbit);
-                                               map_key_clear(BTN_0);
-                                               set_bit(BTN_1, input->keybit);
-                                               set_bit(BTN_2, input->keybit);
-                                               set_bit(BTN_3, input->keybit);
-                                               set_bit(BTN_4, input->keybit);
-                                               set_bit(BTN_5, input->keybit);
+                                               map_key_clear(KEY_F13);
+                                               set_bit(KEY_F14, input->keybit);
+                                               set_bit(KEY_F15, input->keybit);
+                                               set_bit(KEY_F16, input->keybit);
+                                               set_bit(KEY_F17, input->keybit);
+                                               set_bit(KEY_F18, input->keybit);
                                        default:        goto ignore;
                                }
                        } else {
@@ -914,6 +931,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                set_bit(KEY_VOLUMEDOWN, input->keybit);
        }
 
+       if (usage->type == EV_KEY) {
+               set_bit(EV_MSC, input->evbit);
+               set_bit(MSC_SCAN, input->mscbit);
+       }
+
        hid_resolv_event(usage->type, usage->code);
 
        dbg_hid_line("\n");
@@ -928,7 +950,7 @@ ignore:
 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;
+       unsigned *quirks = &hid->quirks;
 
        if (!field->hidinput)
                return;
@@ -1017,16 +1039,16 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
                return;
        }
 
-       /* Handling MS NEK4K special buttons */
-       if (IS_MS_NEK4K(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+       /* Handling MS keyboards special buttons */
+       if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
                int key = 0;
                static int last_key = 0;
                switch (value) {
-                       case 0x01: key = BTN_1; break;
-                       case 0x02: key = BTN_2; break;
-                       case 0x04: key = BTN_3; break;
-                       case 0x08: key = BTN_4; break;
-                       case 0x10: key = BTN_5; break;
+                       case 0x01: key = KEY_F14; break;
+                       case 0x02: key = KEY_F15; break;
+                       case 0x04: key = KEY_F16; break;
+                       case 0x08: key = KEY_F17; break;
+                       case 0x10: key = KEY_F18; break;
                        default: break;
                }
                if (key) {
@@ -1036,6 +1058,9 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
                        input_event(input, usage->type, last_key, 0);
                }
        }
+       /* report the usage code as scancode if the key status has changed */
+       if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
+               input_event(input, EV_MSC, MSC_SCAN, usage->hid);
 
        input_event(input, usage->type, usage->code, value);
 
@@ -1097,6 +1122,9 @@ int hidinput_connect(struct hid_device *hid)
        int i, j, k;
        int max_report_type = HID_OUTPUT_REPORT;
 
+       if (hid->quirks & HID_QUIRK_IGNORE_HIDINPUT)
+               return -1;
+
        INIT_LIST_HEAD(&hid->inputs);
 
        for (i = 0; i < hid->maxcollection; i++)