diff options
| -rw-r--r-- | drivers/input/keyboard/atkbd.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 271c0b7045c3..e9acbe0c9e2a 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -233,6 +233,7 @@ struct atkbd { | |||
| 233 | */ | 233 | */ |
| 234 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); | 234 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); |
| 235 | static void *atkbd_platform_fixup_data; | 235 | static void *atkbd_platform_fixup_data; |
| 236 | static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); | ||
| 236 | 237 | ||
| 237 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 238 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, |
| 238 | ssize_t (*handler)(struct atkbd *, char *)); | 239 | ssize_t (*handler)(struct atkbd *, char *)); |
| @@ -393,6 +394,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
| 393 | 394 | ||
| 394 | input_event(dev, EV_MSC, MSC_RAW, code); | 395 | input_event(dev, EV_MSC, MSC_RAW, code); |
| 395 | 396 | ||
| 397 | if (atkbd_platform_scancode_fixup) | ||
| 398 | code = atkbd_platform_scancode_fixup(atkbd, code); | ||
| 399 | |||
| 396 | if (atkbd->translated) { | 400 | if (atkbd->translated) { |
| 397 | 401 | ||
| 398 | if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { | 402 | if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) { |
| @@ -923,6 +927,22 @@ static unsigned int atkbd_volume_forced_release_keys[] = { | |||
| 923 | }; | 927 | }; |
| 924 | 928 | ||
| 925 | /* | 929 | /* |
| 930 | * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas | ||
| 931 | * they should be generating e4-e6 (0x80 | code). | ||
| 932 | */ | ||
| 933 | static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, | ||
| 934 | unsigned int code) | ||
| 935 | { | ||
| 936 | if (atkbd->translated && atkbd->emul == 1 && | ||
| 937 | (code == 0x64 || code == 0x65 || code == 0x66)) { | ||
| 938 | atkbd->emul = 0; | ||
| 939 | code |= 0x80; | ||
| 940 | } | ||
| 941 | |||
| 942 | return code; | ||
| 943 | } | ||
| 944 | |||
| 945 | /* | ||
| 926 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 946 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
| 927 | * according to the selected scancode set | 947 | * according to the selected scancode set |
| 928 | */ | 948 | */ |
| @@ -1527,6 +1547,13 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) | |||
| 1527 | return 0; | 1547 | return 0; |
| 1528 | } | 1548 | } |
| 1529 | 1549 | ||
| 1550 | static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | ||
| 1551 | { | ||
| 1552 | atkbd_platform_scancode_fixup = id->driver_data; | ||
| 1553 | |||
| 1554 | return 0; | ||
| 1555 | } | ||
| 1556 | |||
| 1530 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | 1557 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { |
| 1531 | { | 1558 | { |
| 1532 | .ident = "Dell Laptop", | 1559 | .ident = "Dell Laptop", |
| @@ -1663,6 +1690,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
| 1663 | .callback = atkbd_setup_forced_release, | 1690 | .callback = atkbd_setup_forced_release, |
| 1664 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 1691 | .driver_data = atkdb_soltech_ta12_forced_release_keys, |
| 1665 | }, | 1692 | }, |
| 1693 | { | ||
| 1694 | .ident = "OQO Model 01+", | ||
| 1695 | .matches = { | ||
| 1696 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | ||
| 1697 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | ||
| 1698 | }, | ||
| 1699 | .callback = atkbd_setup_scancode_fixup, | ||
| 1700 | .driver_data = atkbd_oqo_01plus_scancode_fixup, | ||
| 1701 | }, | ||
| 1666 | { } | 1702 | { } |
| 1667 | }; | 1703 | }; |
| 1668 | 1704 | ||
