aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/atkbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r--drivers/input/keyboard/atkbd.c120
1 files changed, 46 insertions, 74 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 45470f18d7e9..9d940dbb1515 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 */
232static void (*atkbd_platform_fixup)(struct atkbd *); 232static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
233static void *atkbd_platform_fixup_data;
233 234
234static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, 235static 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,56 @@ 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 */
840static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) 840static 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 */
855static 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 */
857static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) 863static 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 */
873static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) 870static 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 */
890static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) 878static 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 */
906static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) 885static 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
913 if (atkbd->set == 2)
914 for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
915 __set_bit(forced_release_keys[i],
916 atkbd->force_release_mask);
917}
918 888
919/* 889/*
920 * atkbd_set_keycode_table() initializes keyboard's keycode table 890 * atkbd_set_keycode_table() initializes keyboard's keycode table
@@ -967,7 +937,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
967 * Perform additional fixups 937 * Perform additional fixups
968 */ 938 */
969 if (atkbd_platform_fixup) 939 if (atkbd_platform_fixup)
970 atkbd_platform_fixup(atkbd); 940 atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data);
971} 941}
972 942
973/* 943/*
@@ -1492,9 +1462,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
1492 return sprintf(buf, "%lu\n", atkbd->err_count); 1462 return sprintf(buf, "%lu\n", atkbd->err_count);
1493} 1463}
1494 1464
1495static int __init atkbd_setup_fixup(const struct dmi_system_id *id) 1465static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
1496{ 1466{
1497 atkbd_platform_fixup = id->driver_data; 1467 atkbd_platform_fixup = atkbd_apply_forced_release_keylist;
1468 atkbd_platform_fixup_data = id->driver_data;
1469
1498 return 0; 1470 return 0;
1499} 1471}
1500 1472
@@ -1505,8 +1477,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1505 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1477 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1506 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ 1478 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
1507 }, 1479 },
1508 .callback = atkbd_setup_fixup, 1480 .callback = atkbd_setup_forced_release,
1509 .driver_data = atkbd_dell_laptop_keymap_fixup, 1481 .driver_data = atkbd_dell_laptop_forced_release_keys,
1510 }, 1482 },
1511 { 1483 {
1512 .ident = "Dell Laptop", 1484 .ident = "Dell Laptop",
@@ -1514,8 +1486,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1514 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 1486 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
1515 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ 1487 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
1516 }, 1488 },
1517 .callback = atkbd_setup_fixup, 1489 .callback = atkbd_setup_forced_release,
1518 .driver_data = atkbd_dell_laptop_keymap_fixup, 1490 .driver_data = atkbd_dell_laptop_forced_release_keys,
1519 }, 1491 },
1520 { 1492 {
1521 .ident = "HP 2133", 1493 .ident = "HP 2133",
@@ -1523,8 +1495,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1523 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 1495 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1524 DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), 1496 DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
1525 }, 1497 },
1526 .callback = atkbd_setup_fixup, 1498 .callback = atkbd_setup_forced_release,
1527 .driver_data = atkbd_hp_keymap_fixup, 1499 .driver_data = atkbd_hp_forced_release_keys,
1528 }, 1500 },
1529 { 1501 {
1530 .ident = "HP Pavilion ZV6100", 1502 .ident = "HP Pavilion ZV6100",
@@ -1532,8 +1504,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1532 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 1504 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1533 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), 1505 DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"),
1534 }, 1506 },
1535 .callback = atkbd_setup_fixup, 1507 .callback = atkbd_setup_forced_release,
1536 .driver_data = atkbd_hp_zv6100_keymap_fixup, 1508 .driver_data = atkbd_hp_zv6100_forced_release_keys,
1537 }, 1509 },
1538 { 1510 {
1539 .ident = "Inventec Symphony", 1511 .ident = "Inventec Symphony",
@@ -1541,8 +1513,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1541 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), 1513 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
1542 DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), 1514 DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
1543 }, 1515 },
1544 .callback = atkbd_setup_fixup, 1516 .callback = atkbd_setup_forced_release,
1545 .driver_data = atkbd_inventec_keymap_fixup, 1517 .driver_data = atkbd_inventec_forced_release_keys,
1546 }, 1518 },
1547 { 1519 {
1548 .ident = "Samsung NC10", 1520 .ident = "Samsung NC10",
@@ -1550,8 +1522,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1550 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 1522 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
1551 DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), 1523 DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
1552 }, 1524 },
1553 .callback = atkbd_setup_fixup, 1525 .callback = atkbd_setup_forced_release,
1554 .driver_data = atkbd_samsung_keymap_fixup, 1526 .driver_data = atkbd_samsung_forced_release_keys,
1555 }, 1527 },
1556 { } 1528 { }
1557}; 1529};