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.c112
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
71static const unsigned short atkbd_set2_keycode[512] = { 71#define ATKBD_KEYMAP_SIZE 512
72
73static 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
102static const unsigned short atkbd_set3_keycode[512] = { 104static 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 */
232static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); 234static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
233static void *atkbd_platform_fixup_data; 235static 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
255ATKBD_DEFINE_ATTR(extra); 257ATKBD_DEFINE_ATTR(extra);
258ATKBD_DEFINE_ATTR(force_release);
256ATKBD_DEFINE_ATTR(scroll); 259ATKBD_DEFINE_ATTR(scroll);
257ATKBD_DEFINE_ATTR(set); 260ATKBD_DEFINE_ATTR(set);
258ATKBD_DEFINE_ATTR(softrepeat); 261ATKBD_DEFINE_ATTR(softrepeat);
@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count);
272 275
273static struct attribute *atkbd_attributes[] = { 276static 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 */
890static 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 */
885static unsigned int atkbd_samsung_forced_release_keys[] = { 897static 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 */
912static 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 */
900static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { 919static 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 */
926static 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
1316static 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
1327static 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
1290static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) 1343static 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