]> err.no Git - linux-2.6/blobdiff - drivers/hid/hid-input.c
HID: proper LED-mapping for SpaceNavigator
[linux-2.6] / drivers / hid / hid-input.c
index d459005062e0015e6a7b8ed07ee58865b2762e94..95b9573c5f93191b20c2360cf8efa5cd93ac8008 100644 (file)
@@ -68,6 +68,7 @@ static const struct {
 #define map_led(c)     do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
 
 #define map_abs_clear(c)       do { map_abs(c); clear_bit(c, bit); } while (0)
+#define map_rel_clear(c)       do { map_rel(c); clear_bit(c, bit); } while (0)
 #define map_key_clear(c)       do { map_key(c); clear_bit(c, bit); } while (0)
 
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
@@ -128,12 +129,6 @@ static struct hidinput_key_translation powerbook_iso_keyboard[] = {
        { }
 };
 
-
-static int usbhid_pb_fnmode = 1;
-module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
-MODULE_PARM_DESC(pb_fnmode,
-               "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
-
 static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from)
 {
        struct hidinput_key_translation *trans;
@@ -160,7 +155,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
                return 1;
        }
 
-       if (usbhid_pb_fnmode) {
+       if (hid->pb_fnmode) {
                int do_translate;
 
                trans = find_translation(powerbook_fn_keys, usage->code);
@@ -169,8 +164,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
                                do_translate = 1;
                        else if (trans->flags & POWERBOOK_FLAG_FKEY)
                                do_translate =
-                                       (usbhid_pb_fnmode == 2 &&  (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
-                                       (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
+                                       (hid->pb_fnmode == 2 &&  (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
+                                       (hid->pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
                        else
                                do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
 
@@ -298,7 +293,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                        }
                        }
 
-                       map_key(code);
+                       map_key_clear(code);
                        break;
 
 
@@ -349,9 +344,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
                                case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
                                        if (field->flags & HID_MAIN_ITEM_RELATIVE)
-                                               map_rel(usage->hid & 0xf);
+                                               map_rel_clear(usage->hid & 0xf);
                                        else
-                                               map_abs(usage->hid & 0xf);
+                                               map_abs_clear(usage->hid & 0xf);
                                        break;
 
                                case HID_GD_HATSWITCH:
@@ -369,9 +364,22 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                        break;
 
                case HID_UP_LED:
-                       if (((usage->hid - 1) & 0xffff) >= LED_MAX)
-                               goto ignore;
-                       map_led((usage->hid - 1) & 0xffff);
+
+                       switch (usage->hid & 0xffff) {                        /* HID-Value:                   */
+                               case 0x01:  map_led (LED_NUML);     break;    /*   "Num Lock"                 */
+                               case 0x02:  map_led (LED_CAPSL);    break;    /*   "Caps Lock"                */
+                               case 0x03:  map_led (LED_SCROLLL);  break;    /*   "Scroll Lock"              */
+                               case 0x04:  map_led (LED_COMPOSE);  break;    /*   "Compose"                  */
+                               case 0x05:  map_led (LED_KANA);     break;    /*   "Kana"                     */
+                               case 0x27:  map_led (LED_SLEEP);    break;    /*   "Stand-By"                 */
+                               case 0x4c:  map_led (LED_SUSPEND);  break;    /*   "System Suspend"           */
+                               case 0x09:  map_led (LED_MUTE);     break;    /*   "Mute"                     */
+                               case 0x4b:  map_led (LED_MISC);     break;    /*   "Generic Indicator"        */
+                               case 0x19:  map_led (LED_MAIL);     break;    /*   "Message Waiting"          */
+                               case 0x4d:  map_led (LED_CHARGING); break;    /*   "External Power Connected" */
+
+                               default: goto ignore;
+                       }
                        break;
 
                case HID_UP_DIGITIZER:
@@ -421,12 +429,31 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x000: goto ignore;
                                case 0x034: map_key_clear(KEY_SLEEP);           break;
                                case 0x036: map_key_clear(BTN_MISC);            break;
+                               case 0x040: map_key_clear(KEY_MENU);            break;
                                case 0x045: map_key_clear(KEY_RADIO);           break;
+
+                               case 0x088: map_key_clear(KEY_PC);              break;
+                               case 0x089: map_key_clear(KEY_TV);              break;
                                case 0x08a: map_key_clear(KEY_WWW);             break;
+                               case 0x08b: map_key_clear(KEY_DVD);             break;
+                               case 0x08c: map_key_clear(KEY_PHONE);           break;
                                case 0x08d: map_key_clear(KEY_PROGRAM);         break;
+                               case 0x08e: map_key_clear(KEY_VIDEOPHONE);      break;
+                               case 0x08f: map_key_clear(KEY_GAMES);           break;
+                               case 0x090: map_key_clear(KEY_MEMO);            break;
+                               case 0x091: map_key_clear(KEY_CD);              break;
+                               case 0x092: map_key_clear(KEY_VCR);             break;
+                               case 0x093: map_key_clear(KEY_TUNER);           break;
+                               case 0x094: map_key_clear(KEY_EXIT);            break;
                                case 0x095: map_key_clear(KEY_HELP);            break;
+                               case 0x096: map_key_clear(KEY_TAPE);            break;
+                               case 0x097: map_key_clear(KEY_TV2);             break;
+                               case 0x098: map_key_clear(KEY_SAT);             break;
+
                                case 0x09c: map_key_clear(KEY_CHANNELUP);       break;
                                case 0x09d: map_key_clear(KEY_CHANNELDOWN);     break;
+                               case 0x0a0: map_key_clear(KEY_VCR2);            break;
+
                                case 0x0b0: map_key_clear(KEY_PLAY);            break;
                                case 0x0b1: map_key_clear(KEY_PAUSE);           break;
                                case 0x0b2: map_key_clear(KEY_RECORD);          break;
@@ -436,6 +463,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);    break;
                                case 0x0b7: map_key_clear(KEY_STOPCD);          break;
                                case 0x0b8: map_key_clear(KEY_EJECTCD);         break;
+
                                case 0x0cd: map_key_clear(KEY_PLAYPAUSE);       break;
                                case 0x0e0: map_abs_clear(ABS_VOLUME);          break;
                                case 0x0e2: map_key_clear(KEY_MUTE);            break;
@@ -443,11 +471,30 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x0e9: map_key_clear(KEY_VOLUMEUP);        break;
                                case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);      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;
+                               case 0x186: map_key_clear(KEY_SPREADSHEET);     break;
+                               case 0x187: map_key_clear(KEY_GRAPHICSEDITOR);  break;
+                               case 0x188: map_key_clear(KEY_PRESENTATION);    break;
+                               case 0x189: map_key_clear(KEY_DATABASE);        break;
                                case 0x18a: map_key_clear(KEY_MAIL);            break;
+                               case 0x18b: map_key_clear(KEY_NEWS);            break;
+                               case 0x18c: map_key_clear(KEY_VOICEMAIL);       break;
+                               case 0x18d: map_key_clear(KEY_ADDRESSBOOK);     break;
+                               case 0x18e: map_key_clear(KEY_CALENDAR);        break;
+                               case 0x191: map_key_clear(KEY_FINANCE);         break;
                                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 0x19e: map_key_clear(KEY_COFFEE);          break;
+                               case 0x1a6: map_key_clear(KEY_HELP);            break;
                                case 0x1a7: map_key_clear(KEY_DOCUMENTS);       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;
+                               case 0x202: map_key_clear(KEY_OPEN);            break;
+                               case 0x203: map_key_clear(KEY_CLOSE);           break;
+                               case 0x204: map_key_clear(KEY_EXIT);            break;
                                case 0x207: map_key_clear(KEY_SAVE);            break;
                                case 0x208: map_key_clear(KEY_PRINT);           break;
                                case 0x209: map_key_clear(KEY_PROPS);           break;
@@ -462,10 +509,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x226: map_key_clear(KEY_STOP);            break;
                                case 0x227: map_key_clear(KEY_REFRESH);         break;
                                case 0x22a: map_key_clear(KEY_BOOKMARKS);       break;
+                               case 0x22d: map_key_clear(KEY_ZOOMIN);          break;
+                               case 0x22e: map_key_clear(KEY_ZOOMOUT);         break;
+                               case 0x22f: map_key_clear(KEY_ZOOMRESET);       break;
                                case 0x233: map_key_clear(KEY_SCROLLUP);        break;
                                case 0x234: map_key_clear(KEY_SCROLLDOWN);      break;
-                               case 0x238: map_rel(REL_HWHEEL);                break;
+                               case 0x238: map_rel_clear(REL_HWHEEL);          break;
+                               case 0x25f: map_key_clear(KEY_CANCEL);          break;
                                case 0x279: map_key_clear(KEY_REDO);            break;
+
                                case 0x289: map_key_clear(KEY_REPLY);           break;
                                case 0x28b: map_key_clear(KEY_FORWARDMAIL);     break;
                                case 0x28c: map_key_clear(KEY_SEND);            break;
@@ -727,8 +779,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
        list_for_each_entry(hidinput, &hid->inputs, list)
                input_sync(hidinput->input);
 }
+EXPORT_SYMBOL_GPL(hidinput_report_event);
 
-static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
 {
        struct hid_report *report;
        int i, j;
@@ -743,6 +796,7 @@ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsign
        }
        return -1;
 }
+EXPORT_SYMBOL_GPL(hidinput_find_field);
 
 /*
  * Register the input device; print a message.
@@ -752,7 +806,6 @@ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsign
 
 int hidinput_connect(struct hid_device *hid)
 {
-       struct usb_device *dev = hid->dev;
        struct hid_report *report;
        struct hid_input *hidinput = NULL;
        struct input_dev *input_dev;
@@ -786,16 +839,18 @@ int hidinput_connect(struct hid_device *hid)
                                }
 
                                input_dev->private = hid;
-                               input_dev->event = hidinput_input_event;
-                               input_dev->open = hidinput_open;
-                               input_dev->close = hidinput_close;
+                               input_dev->event = hid->hidinput_input_event;
+                               input_dev->open = hid->hidinput_open;
+                               input_dev->close = hid->hidinput_close;
 
                                input_dev->name = hid->name;
                                input_dev->phys = hid->phys;
                                input_dev->uniq = hid->uniq;
-                               usb_to_input_id(dev, &input_dev->id);
-                               input_dev->cdev.dev = &hid->intf->dev;
-
+                               input_dev->id.bustype = hid->bus;
+                               input_dev->id.vendor  = hid->vendor;
+                               input_dev->id.product = hid->product;
+                               input_dev->id.version = hid->version;
+                               input_dev->cdev.dev = hid->dev;
                                hidinput->input = input_dev;
                                list_add_tail(&hidinput->list, &hid->inputs);
                        }
@@ -817,16 +872,12 @@ int hidinput_connect(struct hid_device *hid)
                        }
                }
 
-       /* This only gets called when we are a single-input (most of the
-        * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
-        * only useful in this case, and not for multi-input quirks. */
-       if (hidinput) {
-               hid_ff_init(hid);
+       if (hidinput)
                input_register_device(hidinput->input);
-       }
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(hidinput_connect);
 
 void hidinput_disconnect(struct hid_device *hid)
 {
@@ -838,3 +889,5 @@ void hidinput_disconnect(struct hid_device *hid)
                kfree(hidinput);
        }
 }
+EXPORT_SYMBOL_GPL(hidinput_disconnect);
+