Input: atkbd - add a quirk for OQO 01+ multimedia keys

OQO 01+ multimedia keys produce 6x on press, e0 6x upon release.
As a result, Linux thinks that another key has been pressed (or is
repeating), when it is actually a release of the same key. Mangle the
release scancode when running on OQO so that driver recognizes it as
such.

Since the device does not have external PS/2 ports mangling is safe
since there is no chance that an external keyboard is connected.

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by Jamie Lentin and committed by Dmitry Torokhov e5713069 3776989d

+36
+36
drivers/input/keyboard/atkbd.c
··· 233 233 */ 234 234 static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); 235 235 static void *atkbd_platform_fixup_data; 236 + static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); 236 237 237 238 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, 238 239 ssize_t (*handler)(struct atkbd *, char *)); ··· 393 392 goto out; 394 393 395 394 input_event(dev, EV_MSC, MSC_RAW, code); 395 + 396 + if (atkbd_platform_scancode_fixup) 397 + code = atkbd_platform_scancode_fixup(atkbd, code); 396 398 397 399 if (atkbd->translated) { 398 400 ··· 925 921 static unsigned int atkbd_volume_forced_release_keys[] = { 926 922 0xae, 0xb0, -1U 927 923 }; 924 + 925 + /* 926 + * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas 927 + * they should be generating e4-e6 (0x80 | code). 928 + */ 929 + static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, 930 + unsigned int code) 931 + { 932 + if (atkbd->translated && atkbd->emul == 1 && 933 + (code == 0x64 || code == 0x65 || code == 0x66)) { 934 + atkbd->emul = 0; 935 + code |= 0x80; 936 + } 937 + 938 + return code; 939 + } 928 940 929 941 /* 930 942 * atkbd_set_keycode_table() initializes keyboard's keycode table ··· 1547 1527 return 0; 1548 1528 } 1549 1529 1530 + static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) 1531 + { 1532 + atkbd_platform_scancode_fixup = id->driver_data; 1533 + 1534 + return 0; 1535 + } 1536 + 1550 1537 static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { 1551 1538 { 1552 1539 .ident = "Dell Laptop", ··· 1689 1662 }, 1690 1663 .callback = atkbd_setup_forced_release, 1691 1664 .driver_data = atkdb_soltech_ta12_forced_release_keys, 1665 + }, 1666 + { 1667 + .ident = "OQO Model 01+", 1668 + .matches = { 1669 + DMI_MATCH(DMI_SYS_VENDOR, "OQO"), 1670 + DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), 1671 + }, 1672 + .callback = atkbd_setup_scancode_fixup, 1673 + .driver_data = atkbd_oqo_01plus_scancode_fixup, 1692 1674 }, 1693 1675 { } 1694 1676 };