diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-04-08 03:00:33 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-04-08 03:00:33 -0400 |
| commit | ba28f22e7cf16cb310bb491cbb3f7d0d5d1f5c5d (patch) | |
| tree | 6d58e91731385281436da191e82c56cd1627482f /drivers/input/keyboard | |
| parent | 577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff) | |
| parent | 59cc1dd97ca9ac0363ef2f770901fbd86e2b970a (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/keyboard')
| -rw-r--r-- | drivers/input/keyboard/atkbd.c | 135 | ||||
| -rw-r--r-- | drivers/input/keyboard/bf54x-keys.c | 4 | ||||
| -rw-r--r-- | drivers/input/keyboard/hilkbd.c | 140 |
3 files changed, 144 insertions, 135 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 45470f18d7e9..f999dc60c3b8 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -229,7 +229,8 @@ struct atkbd { | |||
| 229 | /* | 229 | /* |
| 230 | * System-specific ketymap fixup routine | 230 | * System-specific ketymap fixup routine |
| 231 | */ | 231 | */ |
| 232 | static void (*atkbd_platform_fixup)(struct atkbd *); | 232 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); |
| 233 | static void *atkbd_platform_fixup_data; | ||
| 233 | 234 | ||
| 234 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 235 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, |
| 235 | ssize_t (*handler)(struct atkbd *, char *)); | 236 | ssize_t (*handler)(struct atkbd *, char *)); |
| @@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio) | |||
| 834 | } | 835 | } |
| 835 | 836 | ||
| 836 | /* | 837 | /* |
| 837 | * Most special keys (Fn+F?) on Dell laptops do not generate release | 838 | * generate release events for the keycodes given in data |
| 838 | * events so we have to do it ourselves. | ||
| 839 | */ | 839 | */ |
| 840 | static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) | 840 | static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd, |
| 841 | const void *data) | ||
| 841 | { | 842 | { |
| 842 | static const unsigned int forced_release_keys[] = { | 843 | const unsigned int *keys = data; |
| 843 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, | 844 | unsigned int i; |
| 844 | }; | ||
| 845 | int i; | ||
| 846 | 845 | ||
| 847 | if (atkbd->set == 2) | 846 | if (atkbd->set == 2) |
| 848 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | 847 | for (i = 0; keys[i] != -1U; i++) |
| 849 | __set_bit(forced_release_keys[i], | 848 | __set_bit(keys[i], atkbd->force_release_mask); |
| 850 | atkbd->force_release_mask); | ||
| 851 | } | 849 | } |
| 852 | 850 | ||
| 853 | /* | 851 | /* |
| 852 | * Most special keys (Fn+F?) on Dell laptops do not generate release | ||
| 853 | * events so we have to do it ourselves. | ||
| 854 | */ | ||
| 855 | static unsigned int atkbd_dell_laptop_forced_release_keys[] = { | ||
| 856 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U | ||
| 857 | }; | ||
| 858 | |||
| 859 | /* | ||
| 854 | * Perform fixup for HP system that doesn't generate release | 860 | * Perform fixup for HP system that doesn't generate release |
| 855 | * for its video switch | 861 | * for its video switch |
| 856 | */ | 862 | */ |
| 857 | static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) | 863 | static unsigned int atkbd_hp_forced_release_keys[] = { |
| 858 | { | 864 | 0x94, -1U |
| 859 | static const unsigned int forced_release_keys[] = { | 865 | }; |
| 860 | 0x94, | ||
| 861 | }; | ||
| 862 | int i; | ||
| 863 | |||
| 864 | if (atkbd->set == 2) | ||
| 865 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
| 866 | __set_bit(forced_release_keys[i], | ||
| 867 | atkbd->force_release_mask); | ||
| 868 | } | ||
| 869 | 866 | ||
| 870 | /* | 867 | /* |
| 871 | * Inventec system with broken key release on volume keys | 868 | * Inventec system with broken key release on volume keys |
| 872 | */ | 869 | */ |
| 873 | static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) | 870 | static unsigned int atkbd_inventec_forced_release_keys[] = { |
| 874 | { | 871 | 0xae, 0xb0, -1U |
| 875 | const unsigned int forced_release_keys[] = { | 872 | }; |
| 876 | 0xae, 0xb0, | ||
| 877 | }; | ||
| 878 | int i; | ||
| 879 | |||
| 880 | if (atkbd->set == 2) | ||
| 881 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
| 882 | __set_bit(forced_release_keys[i], | ||
| 883 | atkbd->force_release_mask); | ||
| 884 | } | ||
| 885 | 873 | ||
| 886 | /* | 874 | /* |
| 887 | * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release | 875 | * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release |
| 888 | * for its volume buttons | 876 | * for its volume buttons |
| 889 | */ | 877 | */ |
| 890 | static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) | 878 | static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { |
| 891 | { | 879 | 0xae, 0xb0, -1U |
| 892 | const unsigned int forced_release_keys[] = { | 880 | }; |
| 893 | 0xae, 0xb0, | ||
| 894 | }; | ||
| 895 | int i; | ||
| 896 | |||
| 897 | if (atkbd->set == 2) | ||
| 898 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
| 899 | __set_bit(forced_release_keys[i], | ||
| 900 | atkbd->force_release_mask); | ||
| 901 | } | ||
| 902 | 881 | ||
| 903 | /* | 882 | /* |
| 904 | * Samsung NC10 with Fn+F? key release not working | 883 | * Samsung NC10 with Fn+F? key release not working |
| 905 | */ | 884 | */ |
| 906 | static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) | 885 | static unsigned int atkbd_samsung_forced_release_keys[] = { |
| 907 | { | 886 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U |
| 908 | const unsigned int forced_release_keys[] = { | 887 | }; |
| 909 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, | ||
| 910 | }; | ||
| 911 | int i; | ||
| 912 | 888 | ||
| 913 | if (atkbd->set == 2) | 889 | /* |
| 914 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | 890 | * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop |
| 915 | __set_bit(forced_release_keys[i], | 891 | * do not generate release events so we have to do it ourselves. |
| 916 | atkbd->force_release_mask); | 892 | */ |
| 917 | } | 893 | static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { |
| 894 | 0xb0, 0xae, -1U | ||
| 895 | }; | ||
| 918 | 896 | ||
| 919 | /* | 897 | /* |
| 920 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 898 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
| @@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) | |||
| 967 | * Perform additional fixups | 945 | * Perform additional fixups |
| 968 | */ | 946 | */ |
| 969 | if (atkbd_platform_fixup) | 947 | if (atkbd_platform_fixup) |
| 970 | atkbd_platform_fixup(atkbd); | 948 | atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data); |
| 971 | } | 949 | } |
| 972 | 950 | ||
| 973 | /* | 951 | /* |
| @@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | |||
| 1492 | return sprintf(buf, "%lu\n", atkbd->err_count); | 1470 | return sprintf(buf, "%lu\n", atkbd->err_count); |
| 1493 | } | 1471 | } |
| 1494 | 1472 | ||
| 1495 | static int __init atkbd_setup_fixup(const struct dmi_system_id *id) | 1473 | static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) |
| 1496 | { | 1474 | { |
| 1497 | atkbd_platform_fixup = id->driver_data; | 1475 | atkbd_platform_fixup = atkbd_apply_forced_release_keylist; |
| 1476 | atkbd_platform_fixup_data = id->driver_data; | ||
| 1477 | |||
| 1498 | return 0; | 1478 | return 0; |
| 1499 | } | 1479 | } |
| 1500 | 1480 | ||
| @@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1505 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1485 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 1506 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1486 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
| 1507 | }, | 1487 | }, |
| 1508 | .callback = atkbd_setup_fixup, | 1488 | .callback = atkbd_setup_forced_release, |
| 1509 | .driver_data = atkbd_dell_laptop_keymap_fixup, | 1489 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
| 1510 | }, | 1490 | }, |
| 1511 | { | 1491 | { |
| 1512 | .ident = "Dell Laptop", | 1492 | .ident = "Dell Laptop", |
| @@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1514 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1494 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
| 1515 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1495 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
| 1516 | }, | 1496 | }, |
| 1517 | .callback = atkbd_setup_fixup, | 1497 | .callback = atkbd_setup_forced_release, |
| 1518 | .driver_data = atkbd_dell_laptop_keymap_fixup, | 1498 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
| 1519 | }, | 1499 | }, |
| 1520 | { | 1500 | { |
| 1521 | .ident = "HP 2133", | 1501 | .ident = "HP 2133", |
| @@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1523 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1503 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
| 1524 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1504 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
| 1525 | }, | 1505 | }, |
| 1526 | .callback = atkbd_setup_fixup, | 1506 | .callback = atkbd_setup_forced_release, |
| 1527 | .driver_data = atkbd_hp_keymap_fixup, | 1507 | .driver_data = atkbd_hp_forced_release_keys, |
| 1528 | }, | 1508 | }, |
| 1529 | { | 1509 | { |
| 1530 | .ident = "HP Pavilion ZV6100", | 1510 | .ident = "HP Pavilion ZV6100", |
| @@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1532 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1512 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
| 1533 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1513 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
| 1534 | }, | 1514 | }, |
| 1535 | .callback = atkbd_setup_fixup, | 1515 | .callback = atkbd_setup_forced_release, |
| 1536 | .driver_data = atkbd_hp_zv6100_keymap_fixup, | 1516 | .driver_data = atkbd_hp_zv6100_forced_release_keys, |
| 1537 | }, | 1517 | }, |
| 1538 | { | 1518 | { |
| 1539 | .ident = "Inventec Symphony", | 1519 | .ident = "Inventec Symphony", |
| @@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1541 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1521 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
| 1542 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1522 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
| 1543 | }, | 1523 | }, |
| 1544 | .callback = atkbd_setup_fixup, | 1524 | .callback = atkbd_setup_forced_release, |
| 1545 | .driver_data = atkbd_inventec_keymap_fixup, | 1525 | .driver_data = atkbd_inventec_forced_release_keys, |
| 1546 | }, | 1526 | }, |
| 1547 | { | 1527 | { |
| 1548 | .ident = "Samsung NC10", | 1528 | .ident = "Samsung NC10", |
| @@ -1550,8 +1530,17 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1550 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1530 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
| 1551 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1531 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
| 1552 | }, | 1532 | }, |
| 1553 | .callback = atkbd_setup_fixup, | 1533 | .callback = atkbd_setup_forced_release, |
| 1554 | .driver_data = atkbd_samsung_keymap_fixup, | 1534 | .driver_data = atkbd_samsung_forced_release_keys, |
| 1535 | }, | ||
| 1536 | { | ||
| 1537 | .ident = "Fujitsu Amilo PA 1510", | ||
| 1538 | .matches = { | ||
| 1539 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 1540 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | ||
| 1541 | }, | ||
| 1542 | .callback = atkbd_setup_forced_release, | ||
| 1543 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, | ||
| 1555 | }, | 1544 | }, |
| 1556 | { } | 1545 | { } |
| 1557 | }; | 1546 | }; |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index ee855c5202e8..e94b7d735aca 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
| @@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
| 211 | 211 | ||
| 212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || | 212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || |
| 213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { | 213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { |
| 214 | printk(KERN_ERR DRV_NAME | 214 | printk(KERN_WARNING DRV_NAME |
| 215 | ": Invalid Debounce/Columdrive Time from pdata\n"); | 215 | ": Invalid Debounce/Columndrive Time in platform data\n"); |
| 216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ | 216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ |
| 217 | } else { | 217 | } else { |
| 218 | bfin_write_KPAD_MSEL( | 218 | bfin_write_KPAD_MSEL( |
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index aacf71f3cd44..e9d639ec283d 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
| @@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | 200 | ||
| 201 | /* initialise HIL */ | 201 | /* initialize HIL */ |
| 202 | static int __init | 202 | static int __devinit hil_keyb_init(void) |
| 203 | hil_keyb_init(void) | ||
| 204 | { | 203 | { |
| 205 | unsigned char c; | 204 | unsigned char c; |
| 206 | unsigned int i, kbid; | 205 | unsigned int i, kbid; |
| 207 | wait_queue_head_t hil_wait; | 206 | wait_queue_head_t hil_wait; |
| 208 | int err; | 207 | int err; |
| 209 | 208 | ||
| 210 | if (hil_dev.dev) { | 209 | if (hil_dev.dev) |
| 211 | return -ENODEV; /* already initialized */ | 210 | return -ENODEV; /* already initialized */ |
| 212 | } | ||
| 213 | 211 | ||
| 212 | init_waitqueue_head(&hil_wait); | ||
| 214 | spin_lock_init(&hil_dev.lock); | 213 | spin_lock_init(&hil_dev.lock); |
| 214 | |||
| 215 | hil_dev.dev = input_allocate_device(); | 215 | hil_dev.dev = input_allocate_device(); |
| 216 | if (!hil_dev.dev) | 216 | if (!hil_dev.dev) |
| 217 | return -ENOMEM; | 217 | return -ENOMEM; |
| 218 | 218 | ||
| 219 | #if defined(CONFIG_HP300) | ||
| 220 | if (!MACH_IS_HP300) { | ||
| 221 | err = -ENODEV; | ||
| 222 | goto err1; | ||
| 223 | } | ||
| 224 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { | ||
| 225 | printk(KERN_ERR "HIL: hardware register was not found\n"); | ||
| 226 | err = -ENODEV; | ||
| 227 | goto err1; | ||
| 228 | } | ||
| 229 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { | ||
| 230 | printk(KERN_ERR "HIL: IOPORT region already used\n"); | ||
| 231 | err = -EIO; | ||
| 232 | goto err1; | ||
| 233 | } | ||
| 234 | #endif | ||
| 235 | |||
| 236 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); | 219 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); |
| 237 | if (err) { | 220 | if (err) { |
| 238 | printk(KERN_ERR "HIL: Can't get IRQ\n"); | 221 | printk(KERN_ERR "HIL: Can't get IRQ\n"); |
| 239 | goto err2; | 222 | goto err1; |
| 240 | } | 223 | } |
| 241 | 224 | ||
| 242 | /* Turn on interrupts */ | 225 | /* Turn on interrupts */ |
| @@ -246,11 +229,9 @@ hil_keyb_init(void) | |||
| 246 | hil_dev.valid = 0; /* clear any pending data */ | 229 | hil_dev.valid = 0; /* clear any pending data */ |
| 247 | hil_do(HIL_READKBDSADR, NULL, 0); | 230 | hil_do(HIL_READKBDSADR, NULL, 0); |
| 248 | 231 | ||
| 249 | init_waitqueue_head(&hil_wait); | 232 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ); |
| 250 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); | 233 | if (!hil_dev.valid) |
| 251 | if (!hil_dev.valid) { | ||
| 252 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); | 234 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); |
| 253 | } | ||
| 254 | 235 | ||
| 255 | c = hil_dev.c; | 236 | c = hil_dev.c; |
| 256 | hil_dev.valid = 0; | 237 | hil_dev.valid = 0; |
| @@ -268,7 +249,7 @@ hil_keyb_init(void) | |||
| 268 | 249 | ||
| 269 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) | 250 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) |
| 270 | if (hphilkeyb_keycode[i] != KEY_RESERVED) | 251 | if (hphilkeyb_keycode[i] != KEY_RESERVED) |
| 271 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); | 252 | __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); |
| 272 | 253 | ||
| 273 | hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 254 | hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
| 274 | hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | 255 | hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | |
| @@ -287,34 +268,45 @@ hil_keyb_init(void) | |||
| 287 | err = input_register_device(hil_dev.dev); | 268 | err = input_register_device(hil_dev.dev); |
| 288 | if (err) { | 269 | if (err) { |
| 289 | printk(KERN_ERR "HIL: Can't register device\n"); | 270 | printk(KERN_ERR "HIL: Can't register device\n"); |
| 290 | goto err3; | 271 | goto err2; |
| 291 | } | 272 | } |
| 273 | |||
| 292 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", | 274 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", |
| 293 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); | 275 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); |
| 294 | 276 | ||
| 295 | return 0; | 277 | return 0; |
| 296 | 278 | ||
| 297 | err3: | 279 | err2: |
| 298 | hil_do(HIL_INTOFF, NULL, 0); | 280 | hil_do(HIL_INTOFF, NULL, 0); |
| 299 | disable_irq(HIL_IRQ); | ||
| 300 | free_irq(HIL_IRQ, hil_dev.dev_id); | 281 | free_irq(HIL_IRQ, hil_dev.dev_id); |
| 301 | err2: | ||
| 302 | #if defined(CONFIG_HP300) | ||
| 303 | release_region(HILBASE + HIL_DATA, 2); | ||
| 304 | err1: | 282 | err1: |
| 305 | #endif | ||
| 306 | input_free_device(hil_dev.dev); | 283 | input_free_device(hil_dev.dev); |
| 307 | hil_dev.dev = NULL; | 284 | hil_dev.dev = NULL; |
| 308 | return err; | 285 | return err; |
| 309 | } | 286 | } |
| 310 | 287 | ||
| 288 | static void __devexit hil_keyb_exit(void) | ||
| 289 | { | ||
| 290 | if (HIL_IRQ) | ||
| 291 | free_irq(HIL_IRQ, hil_dev.dev_id); | ||
| 292 | |||
| 293 | /* Turn off interrupts */ | ||
| 294 | hil_do(HIL_INTOFF, NULL, 0); | ||
| 295 | |||
| 296 | input_unregister_device(hil_dev.dev); | ||
| 297 | hil_dev.dev = NULL; | ||
| 298 | } | ||
| 311 | 299 | ||
| 312 | #if defined(CONFIG_PARISC) | 300 | #if defined(CONFIG_PARISC) |
| 313 | static int __init | 301 | static int __devinit hil_probe_chip(struct parisc_device *dev) |
| 314 | hil_init_chip(struct parisc_device *dev) | ||
| 315 | { | 302 | { |
| 303 | /* Only allow one HIL keyboard */ | ||
| 304 | if (hil_dev.dev) | ||
| 305 | return -ENODEV; | ||
| 306 | |||
| 316 | if (!dev->irq) { | 307 | if (!dev->irq) { |
| 317 | printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start); | 308 | printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n", |
| 309 | (void *)dev->hpa.start); | ||
| 318 | return -ENODEV; | 310 | return -ENODEV; |
| 319 | } | 311 | } |
| 320 | 312 | ||
| @@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev) | |||
| 327 | return hil_keyb_init(); | 319 | return hil_keyb_init(); |
| 328 | } | 320 | } |
| 329 | 321 | ||
| 322 | static int __devexit hil_remove_chip(struct parisc_device *dev) | ||
| 323 | { | ||
| 324 | hil_keyb_exit(); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 330 | static struct parisc_device_id hil_tbl[] = { | 329 | static struct parisc_device_id hil_tbl[] = { |
| 331 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 }, | 330 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 }, |
| 332 | { 0, } | 331 | { 0, } |
| 333 | }; | 332 | }; |
| 334 | 333 | ||
| 334 | #if 0 | ||
| 335 | /* Disabled to avoid conflicts with the HP SDC HIL drivers */ | ||
| 335 | MODULE_DEVICE_TABLE(parisc, hil_tbl); | 336 | MODULE_DEVICE_TABLE(parisc, hil_tbl); |
| 337 | #endif | ||
| 336 | 338 | ||
| 337 | static struct parisc_driver hil_driver = { | 339 | static struct parisc_driver hil_driver = { |
| 338 | .name = "hil", | 340 | .name = "hil", |
| 339 | .id_table = hil_tbl, | 341 | .id_table = hil_tbl, |
| 340 | .probe = hil_init_chip, | 342 | .probe = hil_probe_chip, |
| 343 | .remove = __devexit_p(hil_remove_chip), | ||
| 341 | }; | 344 | }; |
| 342 | #endif /* CONFIG_PARISC */ | ||
| 343 | |||
| 344 | 345 | ||
| 345 | static int __init hil_init(void) | 346 | static int __init hil_init(void) |
| 346 | { | 347 | { |
| 347 | #if defined(CONFIG_PARISC) | ||
| 348 | return register_parisc_driver(&hil_driver); | 348 | return register_parisc_driver(&hil_driver); |
| 349 | #else | ||
| 350 | return hil_keyb_init(); | ||
| 351 | #endif | ||
| 352 | } | 349 | } |
| 353 | 350 | ||
| 354 | |||
| 355 | static void __exit hil_exit(void) | 351 | static void __exit hil_exit(void) |
| 356 | { | 352 | { |
| 357 | if (HIL_IRQ) { | 353 | unregister_parisc_driver(&hil_driver); |
| 358 | disable_irq(HIL_IRQ); | 354 | } |
| 359 | free_irq(HIL_IRQ, hil_dev.dev_id); | 355 | |
| 356 | #else /* !CONFIG_PARISC */ | ||
| 357 | |||
| 358 | static int __init hil_init(void) | ||
| 359 | { | ||
| 360 | int error; | ||
| 361 | |||
| 362 | /* Only allow one HIL keyboard */ | ||
| 363 | if (hil_dev.dev) | ||
| 364 | return -EBUSY; | ||
| 365 | |||
| 366 | if (!MACH_IS_HP300) | ||
| 367 | return -ENODEV; | ||
| 368 | |||
| 369 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { | ||
| 370 | printk(KERN_ERR "HIL: hardware register was not found\n"); | ||
| 371 | return -ENODEV; | ||
| 360 | } | 372 | } |
| 361 | 373 | ||
| 362 | /* Turn off interrupts */ | 374 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { |
| 363 | hil_do(HIL_INTOFF, NULL, 0); | 375 | printk(KERN_ERR "HIL: IOPORT region already used\n"); |
| 376 | return -EIO; | ||
| 377 | } | ||
| 364 | 378 | ||
| 365 | input_unregister_device(hil_dev.dev); | 379 | error = hil_keyb_init(); |
| 380 | if (error) { | ||
| 381 | release_region(HILBASE + HIL_DATA, 2); | ||
| 382 | return error; | ||
| 383 | } | ||
| 366 | 384 | ||
| 367 | hil_dev.dev = NULL; | 385 | return 0; |
| 386 | } | ||
| 368 | 387 | ||
| 369 | #if defined(CONFIG_PARISC) | 388 | static void __exit hil_exit(void) |
| 370 | unregister_parisc_driver(&hil_driver); | 389 | { |
| 371 | #else | 390 | hil_keyb_exit(); |
| 372 | release_region(HILBASE+HIL_DATA, 2); | 391 | release_region(HILBASE + HIL_DATA, 2); |
| 373 | #endif | ||
| 374 | } | 392 | } |
| 375 | 393 | ||
| 394 | #endif /* CONFIG_PARISC */ | ||
| 395 | |||
| 376 | module_init(hil_init); | 396 | module_init(hil_init); |
| 377 | module_exit(hil_exit); | 397 | module_exit(hil_exit); |
