From: Vojtech Pavlik <vojtech@suse.cz>
To: torvalds@transmeta.com, linux-kernel@vger.kernel.org
Subject: [PATCH 2/11] input: Forced release of keys on AT kbds
Date: Fri, 19 Sep 2003 12:26:41 +0200 [thread overview]
Message-ID: <10639672011605@twilight.ucw.cz> (raw)
In-Reply-To: <10639672004187@twilight.ucw.cz>
You can pull this changeset from:
bk://kernel.bkbits.net/vojtech/input
===================================================================
ChangeSet@1.1340, 2003-09-19 00:58:34-07:00, vojtech@suse.cz
input.c:
input: Don't set autorepeat times in core if already set by driver.
atkbd.c:
input: Automatic forced release of keys if keyrelease gets lost
input.c | 6 +
keyboard/atkbd.c | 173 ++++++++++++++++++++++++++++++-------------------------
2 files changed, 99 insertions(+), 80 deletions(-)
===================================================================
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c Fri Sep 19 12:16:46 2003
+++ b/drivers/input/input.c Fri Sep 19 12:16:46 2003
@@ -426,8 +426,10 @@
init_timer(&dev->timer);
dev->timer.data = (long) dev;
dev->timer.function = input_repeat_key;
- dev->rep[REP_DELAY] = HZ/4;
- dev->rep[REP_PERIOD] = HZ/33;
+ if (!dev->rep[REP_DELAY])
+ dev->rep[REP_DELAY] = HZ/4;
+ if (!dev->rep[REP_PERIOD])
+ dev->rep[REP_PERIOD] = HZ/33;
INIT_LIST_HEAD(&dev->h_list);
list_add_tail(&dev->node, &input_dev_list);
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c Fri Sep 19 12:16:46 2003
+++ b/drivers/input/keyboard/atkbd.c Fri Sep 19 12:16:46 2003
@@ -18,6 +18,7 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
+#include <linux/timer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
@@ -40,8 +41,8 @@
static unsigned char atkbd_set2_keycode[512] = {
0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41, 85,
0, 56, 42,182, 29, 16, 2, 89, 0, 0, 44, 31, 30, 17, 3, 90,
- 0, 46, 45, 32, 18, 5, 4, 91, 0, 57, 47, 33, 20, 19, 6, 0,
- 0, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0,
+ 0, 46, 45, 32, 18, 5, 4, 91, 90, 57, 47, 33, 20, 19, 6, 0,
+ 91, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0,
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
122, 89, 40,120, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 0,
85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121, 0,123,
@@ -87,10 +88,10 @@
#define ATKBD_CMD_GSCANSET 0x11f0
#define ATKBD_CMD_SSCANSET 0x10f0
#define ATKBD_CMD_GETID 0x02f2
+#define ATKBD_CMD_SETREP 0x10f3
#define ATKBD_CMD_ENABLE 0x00f4
#define ATKBD_CMD_RESET_DIS 0x00f5
#define ATKBD_CMD_RESET_BAT 0x02ff
-#define ATKBD_CMD_SETALL_MB 0x00f8
#define ATKBD_CMD_RESEND 0x00fe
#define ATKBD_CMD_EX_ENABLE 0x10ea
#define ATKBD_CMD_EX_SETLEDS 0x20eb
@@ -114,12 +115,14 @@
unsigned char keycode[512];
struct input_dev dev;
struct serio *serio;
+ struct timer_list timer;
char name[64];
char phys[32];
unsigned char cmdbuf[4];
unsigned char cmdcnt;
unsigned char set;
unsigned char release;
+ int lastkey;
volatile signed char ack;
unsigned char emul;
unsigned short id;
@@ -142,6 +145,7 @@
printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
#endif
+#if !defined(__i386__) && !defined (__x86_64__)
if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
printk("atkbd.c: frame/parity error: %02x\n", flags);
serio_write(serio, ATKBD_CMD_RESEND);
@@ -151,6 +155,7 @@
if (!flags)
atkbd->resend = 0;
+#endif
switch (code) {
case ATKBD_RET_ACK:
@@ -195,6 +200,14 @@
atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
break;
default:
+
+ if (!atkbd->release) {
+ mod_timer(&atkbd->timer,
+ jiffies + (test_bit(atkbd->keycode[code],
+ &atkbd->dev.key) ? HZ/33 : HZ/4) + HZ/100);
+ atkbd->lastkey = atkbd->keycode[code];
+ }
+
input_regs(&atkbd->dev, regs);
input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
input_sync(&atkbd->dev);
@@ -205,6 +218,13 @@
return IRQ_HANDLED;
}
+static void atkbd_force_key_up(unsigned long data)
+{
+ struct atkbd *atkbd = (void *) data;
+ input_report_key(&atkbd->dev, atkbd->lastkey, 0);
+ input_sync(&atkbd->dev);
+}
+
/*
* atkbd_sendbyte() sends a byte to the keyboard, and waits for
* acknowledge. It doesn't handle resends according to the keyboard
@@ -214,7 +234,7 @@
static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
{
- int timeout = 10000; /* 100 msec */
+ int timeout = 20000; /* 200 msec */
atkbd->ack = 0;
#ifdef ATKBD_DEBUG
@@ -322,13 +342,50 @@
}
/*
- * Enable keyboard.
+ * atkbd_probe() probes for an AT keyboard on a serio port.
*/
-static void atkbd_enable(struct atkbd *atkbd)
+
+static int atkbd_probe(struct atkbd *atkbd)
{
- if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE))
- printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
- atkbd->serio->phys);
+ unsigned char param[2];
+
+/*
+ * Some systems, where the bit-twiddling when testing the io-lines of the
+ * controller may confuse the keyboard need a full reset of the keyboard. On
+ * these systems the BIOS also usually doesn't do it for us.
+ */
+
+ if (atkbd_reset)
+ if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
+ printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
+
+/*
+ * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
+ * Some keyboards report different values, but the first byte is always 0xab or
+ * 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
+ * should make sure we don't try to set the LEDs on it.
+ */
+
+ if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
+
+/*
+ * If the get ID command failed, we check if we can at least set the LEDs on
+ * the keyboard. This should work on every keyboard out there. It also turns
+ * the LEDs off, which we want anyway.
+ */
+ param[0] = 0;
+ if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+ return -1;
+ atkbd->id = 0xabba;
+ return 0;
+ }
+
+ if (param[0] != 0xab && param[0] != 0xac)
+ return -1;
+ atkbd->id = (param[0] << 8) | param[1];
+
+
+ return 0;
}
/*
@@ -365,103 +422,57 @@
return 4;
}
-/*
- * Try to set the set we want.
- */
+ if (atkbd_set != 3)
+ return 2;
- param[0] = atkbd_set;
+ param[0] = 3;
if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET))
return 2;
-/*
- * Read set number. Beware here. Some keyboards always send '2'
- * or some other number regardless into what mode they have been
- * attempted to be set. Other keyboards treat the '0' command as
- * 'set to set 0', and not 'report current set' as they should.
- * In that case we time out, and return 2.
- */
-
param[0] = 0;
if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET))
return 2;
-/*
- * Here we return the set number the keyboard reports about
- * itself.
- */
+ if (param[0] != 3)
+ return 2;
- return (param[0] == 3) ? 3 : 2;
+ return 3;
}
-/*
- * atkbd_probe() probes for an AT keyboard on a serio port.
- */
-
-static int atkbd_probe(struct atkbd *atkbd)
+static int atkbd_enable(struct atkbd *atkbd)
{
- unsigned char param[2];
+ unsigned char param[1];
/*
- * Some systems, where the bit-twiddling when testing the io-lines of the
- * controller may confuse the keyboard need a full reset of the keyboard. On
- * these systems the BIOS also usually doesn't do it for us.
+ * Set the LEDs to a defined state.
*/
- if (atkbd_reset)
- if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
- printk(KERN_WARNING
- "atkbd.c: keyboard reset failed on %s\n",
- atkbd->serio->phys);
+ param[0] = 0;
+ if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+ return -1;
/*
- * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
- * Some keyboards report different values, but the first byte is always 0xab or
- * 0xac. Some old AT keyboards don't report anything.
+ * Set autorepeat to fastest possible.
*/
- if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) {
-
-/*
- * If the get ID command failed, we check if we can at least set the LEDs on
- * the keyboard. This should work on every keyboard out there. It also turns
- * the LEDs off, which we want anyway.
- */
- param[0] = 0;
- if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
- return -1;
- atkbd->id = 0xabba;
- return 0;
- }
-
- if (param[0] != 0xab && param[0] != 0xac)
+ param[0] = 0;
+ if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP))
return -1;
- atkbd->id = (param[0] << 8) | param[1];
/*
- * Set the LEDs to a defined state.
+ * Enable the keyboard to receive keystrokes.
*/
- param[0] = 0;
- if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
+ if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) {
+ printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n",
+ atkbd->serio->phys);
return -1;
+ }
return 0;
}
/*
- * Disable autorepeat. We don't need it, as we do it in software anyway,
- * because that way can get faster repeat, and have less system load (less
- * accesses to the slow ISA hardware). If this fails, we don't care, and will
- * just ignore the repeated keys.
- *
- * This command is for scancode set 3 only.
- */
-static void atkbd_disable_autorepeat(struct atkbd *atkbd)
-{
- atkbd_command(atkbd, NULL, ATKBD_CMD_SETALL_MB);
-}
-
-/*
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot.
*/
@@ -485,7 +496,7 @@
}
/*
- * atkbd_connect() is called when the serio module finds an interface
+ * atkbd_connect() is called when the serio module finds and interface
* that isn't handled yet by an appropriate device driver. We check if
* there is an AT keyboard out there and if yes, we register ourselves
* to the input module.
@@ -513,6 +524,9 @@
atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
} else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ atkbd->dev.rep[REP_DELAY] = HZ/4 + HZ/50;
+ atkbd->dev.rep[REP_PERIOD] = HZ/33;
+
atkbd->serio = serio;
init_input_dev(&atkbd->dev);
@@ -525,6 +539,10 @@
serio->private = atkbd;
+ init_timer(&atkbd->timer);
+ atkbd->timer.data = (long) atkbd;
+ atkbd->timer.function = atkbd_force_key_up;
+
if (serio_open(serio, dev)) {
kfree(atkbd);
return;
@@ -539,9 +557,8 @@
}
atkbd->set = atkbd_set_3(atkbd);
- if (atkbd->set == 3)
- atkbd_disable_autorepeat(atkbd);
atkbd_enable(atkbd);
+
} else {
atkbd->set = 2;
atkbd->id = 0xab00;
next prev parent reply other threads:[~2003-09-19 10:28 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-19 10:26 [PATCH 1/11] input: Restore synaptics pad mode on module unload Vojtech Pavlik
2003-09-19 10:26 ` Vojtech Pavlik [this message]
2003-09-19 10:26 ` [PATCH 3/11] input: Fix Sega Saturn pad support Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 4/11] input: Big Synaptics pad update Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 5/11] input: Fix resume of PS/2 mouse Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 6/11] input: Change name of Synaptics protocol to SynPS/2 Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 7/11] input: Fix psmouse->pktcnt in Synaptics mode Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 8/11] input: Fix the INPUT_KEYCODE macro and its usage Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 9/11] input: Enlarge the timeout for PS/2 mouse full reset Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 10/11] input: Fix I-Force sleeping issues Vojtech Pavlik
2003-09-19 10:26 ` [PATCH 11/11] input: Claim serio early in serio_open() Vojtech Pavlik
2003-09-21 13:02 ` [PATCH 7/11] input: Fix psmouse->pktcnt in Synaptics mode Peter Osterlund
2003-09-21 17:19 ` Vojtech Pavlik
2003-09-22 14:20 ` [PATCH 5/11] input: Fix resume of PS/2 mouse Pavel Machek
2003-09-20 20:31 ` [PATCH 1/11] input: Restore synaptics pad mode on module unload jhf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=10639672011605@twilight.ucw.cz \
--to=vojtech@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.