input: add a driver for the Winbond WPCD376I Consumer IR hardware
[safe/jmp/linux-2.6] / drivers / input / misc / wistron_btns.c
index 72176f3..11fd038 100644 (file)
@@ -243,9 +243,9 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
 #define FE_UNTESTED 0x80
 
 static struct key_entry *keymap; /* = NULL; Current key map */
-static int have_wifi;
-static int have_bluetooth;
-static int have_leds;
+static bool have_wifi;
+static bool have_bluetooth;
+static int leds_present;       /* bitmask of leds present */
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
 {
@@ -254,11 +254,11 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
        keymap = dmi->driver_data;
        for (key = keymap; key->type != KE_END; key++) {
                if (key->type == KE_WIFI)
-                       have_wifi = 1;
+                       have_wifi = true;
                else if (key->type == KE_BLUETOOTH)
-                       have_bluetooth = 1;
+                       have_bluetooth = true;
        }
-       have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
+       leds_present = key->code & (FE_MAIL_LED | FE_WIFI_LED);
 
        return 1;
 }
@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
        { KE_END,  0 }
 };
 
+static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
+       { KE_KEY,       0x01, {KEY_HELP} },          /* Fn+F1 */
+       { KE_KEY,       0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */
+       { KE_BLUETOOTH, 0x30 },                      /* Fn+F10 */
+       { KE_KEY,       0x31, {KEY_MAIL} },          /* mail button */
+       { KE_KEY,       0x36, {KEY_WWW} },           /* www button */
+       { KE_WIFI,      0x78 },                      /* satelite dish button */
+       { KE_END,       0 }
+};
+
 static struct key_entry keymap_fujitsu_n3510[] __initdata = {
        { KE_KEY, 0x11, {KEY_PROG1} },
        { KE_KEY, 0x12, {KEY_PROG2} },
@@ -601,6 +611,34 @@ static struct key_entry keymap_wistron_generic[] __initdata = {
        { KE_END, 0 }
 };
 
+static struct key_entry keymap_aopen_1557[] __initdata = {
+       { KE_KEY,  0x01, {KEY_HELP} },
+       { KE_KEY,  0x11, {KEY_PROG1} },
+       { KE_KEY,  0x12, {KEY_PROG2} },
+       { KE_WIFI, 0x30 },
+       { KE_KEY,  0x22, {KEY_REWIND} },
+       { KE_KEY,  0x23, {KEY_FORWARD} },
+       { KE_KEY,  0x24, {KEY_PLAYPAUSE} },
+       { KE_KEY,  0x25, {KEY_STOPCD} },
+       { KE_KEY,  0x31, {KEY_MAIL} },
+       { KE_KEY,  0x36, {KEY_WWW} },
+       { KE_END,  0 }
+};
+
+static struct key_entry keymap_prestigio[] __initdata = {
+       { KE_KEY,  0x11, {KEY_PROG1} },
+       { KE_KEY,  0x12, {KEY_PROG2} },
+       { KE_WIFI, 0x30 },
+       { KE_KEY,  0x22, {KEY_REWIND} },
+       { KE_KEY,  0x23, {KEY_FORWARD} },
+       { KE_KEY,  0x24, {KEY_PLAYPAUSE} },
+       { KE_KEY,  0x25, {KEY_STOPCD} },
+       { KE_KEY,  0x31, {KEY_MAIL} },
+       { KE_KEY,  0x36, {KEY_WWW} },
+       { KE_END,  0 }
+};
+
+
 /*
  * If your machine is not here (which is currently rather likely), please send
  * a list of buttons and their key codes (reported when loading this module
@@ -618,6 +656,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
        },
        {
                .callback = dmi_matched,
+               .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
+               },
+               .driver_data = keymap_fs_amilo_pro_v3505
+       },
+       {
+               .callback = dmi_matched,
                .ident = "Fujitsu-Siemens Amilo M7400",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
@@ -627,6 +674,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
        },
        {
                .callback = dmi_matched,
+               .ident = "Maxdata Pro 7000 DX",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
+               },
+               .driver_data = keymap_fs_amilo_pro_v2000
+       },
+       {
+               .callback = dmi_matched,
                .ident = "Fujitsu N3510",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
@@ -943,6 +999,10 @@ static int __init select_keymap(void)
        if (keymap_name != NULL) {
                if (strcmp (keymap_name, "1557/MS2141") == 0)
                        keymap = keymap_wistron_ms2141;
+               else if (strcmp (keymap_name, "aopen1557") == 0)
+                       keymap = keymap_aopen_1557;
+               else if (strcmp (keymap_name, "prestigio") == 0)
+                       keymap = keymap_prestigio;
                else if (strcmp (keymap_name, "generic") == 0)
                        keymap = keymap_wistron_generic;
                else {
@@ -965,8 +1025,8 @@ static int __init select_keymap(void)
 
 static struct input_polled_dev *wistron_idev;
 static unsigned long jiffies_last_press;
-static int wifi_enabled;
-static int bluetooth_enabled;
+static bool wifi_enabled;
+static bool bluetooth_enabled;
 
 static void report_key(struct input_dev *dev, unsigned int keycode)
 {
@@ -1009,24 +1069,24 @@ static struct led_classdev wistron_wifi_led = {
 
 static void __devinit wistron_led_init(struct device *parent)
 {
-       if (have_leds & FE_WIFI_LED) {
+       if (leds_present & FE_WIFI_LED) {
                u16 wifi = bios_get_default_setting(WIFI);
                if (wifi & 1) {
                        wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
                        if (led_classdev_register(parent, &wistron_wifi_led))
-                               have_leds &= ~FE_WIFI_LED;
+                               leds_present &= ~FE_WIFI_LED;
                        else
                                bios_set_state(WIFI, wistron_wifi_led.brightness);
 
                } else
-                       have_leds &= ~FE_WIFI_LED;
+                       leds_present &= ~FE_WIFI_LED;
        }
 
-       if (have_leds & FE_MAIL_LED) {
+       if (leds_present & FE_MAIL_LED) {
                /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
                wistron_mail_led.brightness = LED_OFF;
                if (led_classdev_register(parent, &wistron_mail_led))
-                       have_leds &= ~FE_MAIL_LED;
+                       leds_present &= ~FE_MAIL_LED;
                else
                        bios_set_state(MAIL_LED, wistron_mail_led.brightness);
        }
@@ -1034,28 +1094,28 @@ static void __devinit wistron_led_init(struct device *parent)
 
 static void __devexit wistron_led_remove(void)
 {
-       if (have_leds & FE_MAIL_LED)
+       if (leds_present & FE_MAIL_LED)
                led_classdev_unregister(&wistron_mail_led);
 
-       if (have_leds & FE_WIFI_LED)
+       if (leds_present & FE_WIFI_LED)
                led_classdev_unregister(&wistron_wifi_led);
 }
 
 static inline void wistron_led_suspend(void)
 {
-       if (have_leds & FE_MAIL_LED)
+       if (leds_present & FE_MAIL_LED)
                led_classdev_suspend(&wistron_mail_led);
 
-       if (have_leds & FE_WIFI_LED)
+       if (leds_present & FE_WIFI_LED)
                led_classdev_suspend(&wistron_wifi_led);
 }
 
 static inline void wistron_led_resume(void)
 {
-       if (have_leds & FE_MAIL_LED)
+       if (leds_present & FE_MAIL_LED)
                led_classdev_resume(&wistron_mail_led);
 
-       if (have_leds & FE_WIFI_LED)
+       if (leds_present & FE_WIFI_LED)
                led_classdev_resume(&wistron_wifi_led);
 }
 
@@ -1186,7 +1246,7 @@ static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
 
 static int __devinit setup_input_dev(void)
 {
-       const struct key_entry *key;
+       struct key_entry *key;
        struct input_dev *input_dev;
        int error;
 
@@ -1219,6 +1279,23 @@ static int __devinit setup_input_dev(void)
                                set_bit(key->sw.code, input_dev->swbit);
                                break;
 
+                       /* if wifi or bluetooth are not available, create normal keys */
+                       case KE_WIFI:
+                               if (!have_wifi) {
+                                       key->type = KE_KEY;
+                                       key->keycode = KEY_WLAN;
+                                       key--;
+                               }
+                               break;
+
+                       case KE_BLUETOOTH:
+                               if (!have_bluetooth) {
+                                       key->type = KE_KEY;
+                                       key->keycode = KEY_BLUETOOTH;
+                                       key--;
+                               }
+                               break;
+
                        default:
                                break;
                }
@@ -1251,7 +1328,7 @@ static int __devinit wistron_probe(struct platform_device *dev)
        if (have_wifi) {
                u16 wifi = bios_get_default_setting(WIFI);
                if (wifi & 1)
-                       wifi_enabled = (wifi & 2) ? 1 : 0;
+                       wifi_enabled = wifi & 2;
                else
                        have_wifi = 0;
 
@@ -1262,15 +1339,16 @@ static int __devinit wistron_probe(struct platform_device *dev)
        if (have_bluetooth) {
                u16 bt = bios_get_default_setting(BLUETOOTH);
                if (bt & 1)
-                       bluetooth_enabled = (bt & 2) ? 1 : 0;
+                       bluetooth_enabled = bt & 2;
                else
-                       have_bluetooth = 0;
+                       have_bluetooth = false;
 
                if (have_bluetooth)
                        bios_set_state(BLUETOOTH, bluetooth_enabled);
        }
 
        wistron_led_init(&dev->dev);
+
        err = setup_input_dev();
        if (err) {
                bios_detach();
@@ -1291,7 +1369,7 @@ static int __devexit wistron_remove(struct platform_device *dev)
 }
 
 #ifdef CONFIG_PM
-static int wistron_suspend(struct platform_device *dev, pm_message_t state)
+static int wistron_suspend(struct device *dev)
 {
        if (have_wifi)
                bios_set_state(WIFI, 0);
@@ -1300,10 +1378,11 @@ static int wistron_suspend(struct platform_device *dev, pm_message_t state)
                bios_set_state(BLUETOOTH, 0);
 
        wistron_led_suspend();
+
        return 0;
 }
 
-static int wistron_resume(struct platform_device *dev)
+static int wistron_resume(struct device *dev)
 {
        if (have_wifi)
                bios_set_state(WIFI, wifi_enabled);
@@ -1312,24 +1391,30 @@ static int wistron_resume(struct platform_device *dev)
                bios_set_state(BLUETOOTH, bluetooth_enabled);
 
        wistron_led_resume();
+
        poll_bios(true);
 
        return 0;
 }
-#else
-#define wistron_suspend                NULL
-#define wistron_resume         NULL
+
+static const struct dev_pm_ops wistron_pm_ops = {
+       .suspend        = wistron_suspend,
+       .resume         = wistron_resume,
+       .poweroff       = wistron_suspend,
+       .restore        = wistron_resume,
+};
 #endif
 
 static struct platform_driver wistron_driver = {
        .driver         = {
                .name   = "wistron-bios",
                .owner  = THIS_MODULE,
+#if CONFIG_PM
+               .pm     = &wistron_pm_ops,
+#endif
        },
        .probe          = wistron_probe,
        .remove         = __devexit_p(wistron_remove),
-       .suspend        = wistron_suspend,
-       .resume         = wistron_resume,
 };
 
 static int __init wb_module_init(void)