diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-11-06 02:00:48 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-11-06 02:00:48 -0500 |
| commit | 02cee68998010c4a2cc2383c86babc2ecc737183 (patch) | |
| tree | 13c6483472f672c3b2570b075ed2ad4fd4c5405e /drivers/input/keyboard | |
| parent | f5ba35023697e54a24487bcd822194390a333893 (diff) | |
| parent | b419148e567728f6af0c3b01965c1cc141e3e13a (diff) | |
Merge commit 'v2.6.32-rc6' into next
Diffstat (limited to 'drivers/input/keyboard')
| -rw-r--r-- | drivers/input/keyboard/atkbd.c | 132 | ||||
| -rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 1 |
2 files changed, 92 insertions, 41 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 4709e15af607..4452eabbee6d 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)) { |
| @@ -574,11 +578,22 @@ static void atkbd_event_work(struct work_struct *work) | |||
| 574 | 578 | ||
| 575 | mutex_lock(&atkbd->event_mutex); | 579 | mutex_lock(&atkbd->event_mutex); |
| 576 | 580 | ||
| 577 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) | 581 | if (!atkbd->enabled) { |
| 578 | atkbd_set_leds(atkbd); | 582 | /* |
| 583 | * Serio ports are resumed asynchronously so while driver core | ||
| 584 | * thinks that device is already fully operational in reality | ||
| 585 | * it may not be ready yet. In this case we need to keep | ||
| 586 | * rescheduling till reconnect completes. | ||
| 587 | */ | ||
| 588 | schedule_delayed_work(&atkbd->event_work, | ||
| 589 | msecs_to_jiffies(100)); | ||
| 590 | } else { | ||
| 591 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) | ||
| 592 | atkbd_set_leds(atkbd); | ||
| 579 | 593 | ||
| 580 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) | 594 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) |
| 581 | atkbd_set_repeat_rate(atkbd); | 595 | atkbd_set_repeat_rate(atkbd); |
| 596 | } | ||
| 582 | 597 | ||
| 583 | mutex_unlock(&atkbd->event_mutex); | 598 | mutex_unlock(&atkbd->event_mutex); |
| 584 | } | 599 | } |
| @@ -770,6 +785,30 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra | |||
| 770 | return 3; | 785 | return 3; |
| 771 | } | 786 | } |
| 772 | 787 | ||
| 788 | static int atkbd_reset_state(struct atkbd *atkbd) | ||
| 789 | { | ||
| 790 | struct ps2dev *ps2dev = &atkbd->ps2dev; | ||
| 791 | unsigned char param[1]; | ||
| 792 | |||
| 793 | /* | ||
| 794 | * Set the LEDs to a predefined state (all off). | ||
| 795 | */ | ||
| 796 | |||
| 797 | param[0] = 0; | ||
| 798 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) | ||
| 799 | return -1; | ||
| 800 | |||
| 801 | /* | ||
| 802 | * Set autorepeat to fastest possible. | ||
| 803 | */ | ||
| 804 | |||
| 805 | param[0] = 0; | ||
| 806 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP)) | ||
| 807 | return -1; | ||
| 808 | |||
| 809 | return 0; | ||
| 810 | } | ||
| 811 | |||
| 773 | static int atkbd_activate(struct atkbd *atkbd) | 812 | static int atkbd_activate(struct atkbd *atkbd) |
| 774 | { | 813 | { |
| 775 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 814 | struct ps2dev *ps2dev = &atkbd->ps2dev; |
| @@ -852,29 +891,6 @@ static unsigned int atkbd_hp_forced_release_keys[] = { | |||
| 852 | }; | 891 | }; |
| 853 | 892 | ||
| 854 | /* | 893 | /* |
| 855 | * Inventec system with broken key release on volume keys | ||
| 856 | */ | ||
| 857 | static unsigned int atkbd_inventec_forced_release_keys[] = { | ||
| 858 | 0xae, 0xb0, -1U | ||
| 859 | }; | ||
| 860 | |||
| 861 | /* | ||
| 862 | * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release | ||
| 863 | * for its volume buttons | ||
| 864 | */ | ||
| 865 | static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { | ||
| 866 | 0xae, 0xb0, -1U | ||
| 867 | }; | ||
| 868 | |||
| 869 | /* | ||
| 870 | * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate | ||
| 871 | * release for their volume buttons | ||
| 872 | */ | ||
| 873 | static unsigned int atkbd_hp_r4000_forced_release_keys[] = { | ||
| 874 | 0xae, 0xb0, -1U | ||
| 875 | }; | ||
| 876 | |||
| 877 | /* | ||
| 878 | * Samsung NC10,NC20 with Fn+F? key release not working | 894 | * Samsung NC10,NC20 with Fn+F? key release not working |
| 879 | */ | 895 | */ |
| 880 | static unsigned int atkbd_samsung_forced_release_keys[] = { | 896 | static unsigned int atkbd_samsung_forced_release_keys[] = { |
| @@ -882,14 +898,6 @@ static unsigned int atkbd_samsung_forced_release_keys[] = { | |||
| 882 | }; | 898 | }; |
| 883 | 899 | ||
| 884 | /* | 900 | /* |
| 885 | * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop | ||
| 886 | * do not generate release events so we have to do it ourselves. | ||
| 887 | */ | ||
| 888 | static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { | ||
| 889 | 0xb0, 0xae, -1U | ||
| 890 | }; | ||
| 891 | |||
| 892 | /* | ||
| 893 | * Amilo Pi 3525 key release for Fn+Volume keys not working | 901 | * Amilo Pi 3525 key release for Fn+Volume keys not working |
| 894 | */ | 902 | */ |
| 895 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { | 903 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { |
| @@ -911,6 +919,30 @@ static unsigned int atkdb_soltech_ta12_forced_release_keys[] = { | |||
| 911 | }; | 919 | }; |
| 912 | 920 | ||
| 913 | /* | 921 | /* |
| 922 | * Many notebooks don't send key release event for volume up/down | ||
| 923 | * keys, with key list below common among them | ||
| 924 | */ | ||
| 925 | static unsigned int atkbd_volume_forced_release_keys[] = { | ||
| 926 | 0xae, 0xb0, -1U | ||
| 927 | }; | ||
| 928 | |||
| 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 | /* | ||
| 914 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 946 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
| 915 | * according to the selected scancode set | 947 | * according to the selected scancode set |
| 916 | */ | 948 | */ |
| @@ -1087,6 +1119,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
| 1087 | } | 1119 | } |
| 1088 | 1120 | ||
| 1089 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); | 1121 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); |
| 1122 | atkbd_reset_state(atkbd); | ||
| 1090 | atkbd_activate(atkbd); | 1123 | atkbd_activate(atkbd); |
| 1091 | 1124 | ||
| 1092 | } else { | 1125 | } else { |
| @@ -1267,6 +1300,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun | |||
| 1267 | 1300 | ||
| 1268 | atkbd->dev = new_dev; | 1301 | atkbd->dev = new_dev; |
| 1269 | atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); | 1302 | atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); |
| 1303 | atkbd_reset_state(atkbd); | ||
| 1270 | atkbd_activate(atkbd); | 1304 | atkbd_activate(atkbd); |
| 1271 | atkbd_set_keycode_table(atkbd); | 1305 | a |
