diff options
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 112 |
1 files changed, 105 insertions, 7 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index df3f8aa68115..adb09e2ba394 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -68,7 +68,9 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and | |||
68 | * are loadable via a userland utility. | 68 | * are loadable via a userland utility. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | static const unsigned short atkbd_set2_keycode[512] = { | 71 | #define ATKBD_KEYMAP_SIZE 512 |
72 | |||
73 | static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = { | ||
72 | 74 | ||
73 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES | 75 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES |
74 | 76 | ||
@@ -99,7 +101,7 @@ static const unsigned short atkbd_set2_keycode[512] = { | |||
99 | #endif | 101 | #endif |
100 | }; | 102 | }; |
101 | 103 | ||
102 | static const unsigned short atkbd_set3_keycode[512] = { | 104 | static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = { |
103 | 105 | ||
104 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, | 106 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, |
105 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, | 107 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, |
@@ -200,8 +202,8 @@ struct atkbd { | |||
200 | char phys[32]; | 202 | char phys[32]; |
201 | 203 | ||
202 | unsigned short id; | 204 | unsigned short id; |
203 | unsigned short keycode[512]; | 205 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; |
204 | DECLARE_BITMAP(force_release_mask, 512); | 206 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); |
205 | unsigned char set; | 207 | unsigned char set; |
206 | unsigned char translated; | 208 | unsigned char translated; |
207 | unsigned char extra; | 209 | unsigned char extra; |
@@ -227,7 +229,7 @@ struct atkbd { | |||
227 | }; | 229 | }; |
228 | 230 | ||
229 | /* | 231 | /* |
230 | * System-specific ketymap fixup routine | 232 | * System-specific keymap fixup routine |
231 | */ | 233 | */ |
232 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); | 234 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); |
233 | static void *atkbd_platform_fixup_data; | 235 | static void *atkbd_platform_fixup_data; |
@@ -253,6 +255,7 @@ static struct device_attribute atkbd_attr_##_name = \ | |||
253 | __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); | 255 | __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); |
254 | 256 | ||
255 | ATKBD_DEFINE_ATTR(extra); | 257 | ATKBD_DEFINE_ATTR(extra); |
258 | ATKBD_DEFINE_ATTR(force_release); | ||
256 | ATKBD_DEFINE_ATTR(scroll); | 259 | ATKBD_DEFINE_ATTR(scroll); |
257 | ATKBD_DEFINE_ATTR(set); | 260 | ATKBD_DEFINE_ATTR(set); |
258 | ATKBD_DEFINE_ATTR(softrepeat); | 261 | ATKBD_DEFINE_ATTR(softrepeat); |
@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count); | |||
272 | 275 | ||
273 | static struct attribute *atkbd_attributes[] = { | 276 | static struct attribute *atkbd_attributes[] = { |
274 | &atkbd_attr_extra.attr, | 277 | &atkbd_attr_extra.attr, |
278 | &atkbd_attr_force_release.attr, | ||
275 | &atkbd_attr_scroll.attr, | 279 | &atkbd_attr_scroll.attr, |
276 | &atkbd_attr_set.attr, | 280 | &atkbd_attr_set.attr, |
277 | &atkbd_attr_softrepeat.attr, | 281 | &atkbd_attr_softrepeat.attr, |
@@ -880,6 +884,14 @@ static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { | |||
880 | }; | 884 | }; |
881 | 885 | ||
882 | /* | 886 | /* |
887 | * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate | ||
888 | * release for their volume buttons | ||
889 | */ | ||
890 | static unsigned int atkbd_hp_r4000_forced_release_keys[] = { | ||
891 | 0xae, 0xb0, -1U | ||
892 | }; | ||
893 | |||
894 | /* | ||
883 | * Samsung NC10,NC20 with Fn+F? key release not working | 895 | * Samsung NC10,NC20 with Fn+F? key release not working |
884 | */ | 896 | */ |
885 | static unsigned int atkbd_samsung_forced_release_keys[] = { | 897 | static unsigned int atkbd_samsung_forced_release_keys[] = { |
@@ -895,6 +907,13 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { | |||
895 | }; | 907 | }; |
896 | 908 | ||
897 | /* | 909 | /* |
910 | * Amilo Pi 3525 key release for Fn+Volume keys not working | ||
911 | */ | ||
912 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { | ||
913 | 0x20, 0xa0, 0x2e, 0xae, 0x30, 0xb0, -1U | ||
914 | }; | ||
915 | |||
916 | /* | ||
898 | * Amilo Xi 3650 key release for light touch bar not working | 917 | * Amilo Xi 3650 key release for light touch bar not working |
899 | */ | 918 | */ |
900 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | 919 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { |
@@ -902,6 +921,13 @@ static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | |||
902 | }; | 921 | }; |
903 | 922 | ||
904 | /* | 923 | /* |
924 | * Soltech TA12 system with broken key release on volume keys and mute key | ||
925 | */ | ||
926 | static unsigned int atkdb_soltech_ta12_forced_release_keys[] = { | ||
927 | 0xa0, 0xae, 0xb0, -1U | ||
928 | }; | ||
929 | |||
930 | /* | ||
905 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 931 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
906 | * according to the selected scancode set | 932 | * according to the selected scancode set |
907 | */ | 933 | */ |
@@ -912,7 +938,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) | |||
912 | int i, j; | 938 | int i, j; |
913 | 939 | ||
914 | memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); | 940 | memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); |
915 | bitmap_zero(atkbd->force_release_mask, 512); | 941 | bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); |
916 | 942 | ||
917 | if (atkbd->translated) { | 943 | if (atkbd->translated) { |
918 | for (i = 0; i < 128; i++) { | 944 | for (i = 0; i < 128; i++) { |
@@ -1019,7 +1045,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
1019 | input_dev->keycodesize = sizeof(unsigned short); | 1045 | input_dev->keycodesize = sizeof(unsigned short); |
1020 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 1046 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
1021 | 1047 | ||
1022 | for (i = 0; i < 512; i++) | 1048 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) |
1023 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 1049 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) |
1024 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 1050 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
1025 | } | 1051 | } |
@@ -1287,6 +1313,33 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
1287 | return count; | 1313 | return count; |
1288 | } | 1314 | } |
1289 | 1315 | ||
1316 | static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf) | ||
1317 | { | ||
1318 | size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, | ||
1319 | atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); | ||
1320 | |||
1321 | buf[len++] = '\n'; | ||
1322 | buf[len] = '\0'; | ||
1323 | |||
1324 | return len; | ||
1325 | } | ||
1326 | |||
1327 | static ssize_t atkbd_set_force_release(struct atkbd *atkbd, | ||
1328 | const char *buf, size_t count) | ||
1329 | { | ||
1330 | /* 64 bytes on stack should be acceptable */ | ||
1331 | DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE); | ||
1332 | int err; | ||
1333 | |||
1334 | err = bitmap_parselist(buf, new_mask, ATKBD_KEYMAP_SIZE); | ||
1335 | if (err) | ||
1336 | return err; | ||
1337 | |||
1338 | memcpy(atkbd->force_release_mask, new_mask, sizeof(atkbd->force_release_mask)); | ||
1339 | return count; | ||
1340 | } | ||
1341 | |||
1342 | |||
1290 | static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) | 1343 | static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) |
1291 | { | 1344 | { |
1292 | return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); | 1345 | return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); |
@@ -1523,6 +1576,33 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1523 | .driver_data = atkbd_hp_zv6100_forced_release_keys, | 1576 | .driver_data = atkbd_hp_zv6100_forced_release_keys, |
1524 | }, | 1577 | }, |
1525 | { | 1578 | { |
1579 | .ident = "HP Presario R4000", | ||
1580 | .matches = { | ||
1581 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1582 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | ||
1583 | }, | ||
1584 | .callback = atkbd_setup_forced_release, | ||
1585 | .driver_data = atkbd_hp_r4000_forced_release_keys, | ||
1586 | }, | ||
1587 | { | ||
1588 | .ident = "HP Presario R4100", | ||
1589 | .matches = { | ||
1590 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1591 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | ||
1592 | }, | ||
1593 | .callback = atkbd_setup_forced_release, | ||
1594 | .driver_data = atkbd_hp_r4000_forced_release_keys, | ||
1595 | }, | ||
1596 | { | ||
1597 | .ident = "HP Presario R4200", | ||
1598 | .matches = { | ||
1599 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1600 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | ||
1601 | }, | ||
1602 | .callback = atkbd_setup_forced_release, | ||
1603 | .driver_data = atkbd_hp_r4000_forced_release_keys, | ||
1604 | }, | ||
1605 | { | ||
1526 | .ident = "Inventec Symphony", | 1606 | .ident = "Inventec Symphony", |
1527 | .matches = { | 1607 | .matches = { |
1528 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1608 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
@@ -1568,6 +1648,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1568 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, | 1648 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, |
1569 | }, | 1649 | }, |
1570 | { | 1650 | { |
1651 | .ident = "Fujitsu Amilo Pi 3525", | ||
1652 | .matches = { | ||
1653 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
1654 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | ||
1655 | }, | ||
1656 | .callback = atkbd_setup_forced_release, | ||
1657 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | ||
1658 | }, | ||
1659 | { | ||
1571 | .ident = "Fujitsu Amilo Xi 3650", | 1660 | .ident = "Fujitsu Amilo Xi 3650", |
1572 | .matches = { | 1661 | .matches = { |
1573 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1662 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
@@ -1576,6 +1665,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1576 | .callback = atkbd_setup_forced_release, | 1665 | .callback = atkbd_setup_forced_release, |
1577 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1666 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1578 | }, | 1667 | }, |
1668 | { | ||
1669 | .ident = "Soltech Corporation TA12", | ||
1670 | .matches = { | ||
1671 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | ||
1672 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | ||
1673 | }, | ||
1674 | .callback = atkbd_setup_forced_release, | ||
1675 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | ||
1676 | }, | ||
1579 | { } | 1677 | { } |
1580 | }; | 1678 | }; |
1581 | 1679 | ||