summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSigrid <ftrvxmtrx@gmail.com>2020-03-28 15:37:48 +0100
committerSigrid <ftrvxmtrx@gmail.com>2020-03-28 15:37:48 +0100
commit90143609212ed4500409a64d26f6b12d097b13ed (patch)
treeb986f1611468db5e8cf86c8b1196b4b6b385e8c3 /sys
parent47e3c088c90944e49041c8b210dd7169479738da (diff)
kbd: add "repeat" file to set typematic repeat rate/delay on PS/2 keyboards
Diffstat (limited to 'sys')
-rw-r--r--sys/man/3/kbd21
-rw-r--r--sys/src/9/pc/devkbd.c34
2 files changed, 48 insertions, 7 deletions
diff --git a/sys/man/3/kbd b/sys/man/3/kbd
index 3d95cb4e8..82422c7dd 100644
--- a/sys/man/3/kbd
+++ b/sys/man/3/kbd
@@ -7,15 +7,17 @@ kbd \- pc keyboard driver
.B /dev/scancode
.B /dev/leds
+.B /dev/repeat
.fi
.SH DESCRIPTION
.PP
The
.I kbd
device serves a one-level directory containing the files
-.BR scancode
+.BR scancode ,
+.BR leds
and
-.BR leds .
+.BR repeat .
.PP
Reading the
.BR scancode
@@ -29,14 +31,27 @@ file can be only opened once by the hostowner.
.PP
Writing a number to the write-only
.BR leds
-file changes the status leds on the keyboard. the value of the
+file changes the status leds on the keyboard. The value of the
number is the addition of 1, 2 and 4 representing activated
Scroll, Num and Caps leds.
+.PP
+The
+.BR repeat
+file sets typematic rate and delay. The value of the number is a
+bitmask where first 5 bits set the repeat rate (ranging from 0b00000
+for 30Hz to 0b11111 for 2Hz). Bits 6 and 7 set the delay before the
+first repeat is activated (ranging from 0b00 for 250Hz to 0b11 for
+1000Hz).
.SH EXAMPLE
Set the Scroll and Caps leds:
.EX
echo 5 >/dev/leds
.EE
+.PP
+Enable fast repeat rate and the least delay:
+.EX
+echo 0 >/dev/repeat
+.EE
.SH "SEE ALSO"
.IR kbdfs (8)
.SH SOURCE
diff --git a/sys/src/9/pc/devkbd.c b/sys/src/9/pc/devkbd.c
index 5aeaded1f..5f6865ef1 100644
--- a/sys/src/9/pc/devkbd.c
+++ b/sys/src/9/pc/devkbd.c
@@ -40,12 +40,14 @@ enum {
Qdir,
Qscancode,
Qleds,
+ Qrepeat,
};
static Dirtab kbdtab[] = {
".", {Qdir, 0, QTDIR}, 0, 0555,
"scancode", {Qscancode, 0}, 0, 0440,
"leds", {Qleds, 0}, 0, 0220,
+ "repeat", {Qrepeat, 0}, 0, 0220,
};
static Lock i8042lock;
@@ -193,6 +195,28 @@ setleds(int leds)
iunlock(&i8042lock);
}
+static void
+setrepeat(int repeat)
+{
+ if(nokbd)
+ return;
+
+ repeat &= 0x7f;
+ ilock(&i8042lock);
+ for(;;){
+ if(outready() < 0)
+ break;
+ outb(Data, 0xf3); /* `set typematic rate and delay' */
+ if(outready() < 0)
+ break;
+ outb(Data, repeat);
+ if(outready() < 0)
+ break;
+ break;
+ }
+ iunlock(&i8042lock);
+}
+
/*
* keyboard interrupt
*/
@@ -357,16 +381,18 @@ kbdwrite(Chan *c, void *a, long n, vlong)
{
char tmp[8+1], *p;
- if(c->qid.path != Qleds)
- error(Egreg);
-
p = tmp + n;
if(n >= sizeof(tmp))
p = tmp + sizeof(tmp)-1;
memmove(tmp, a, p - tmp);
*p = 0;
- setleds(atoi(tmp));
+ if(c->qid.path == Qleds)
+ setleds(atoi(tmp));
+ else if(c->qid.path == Qrepeat)
+ setrepeat(atoi(tmp));
+ else
+ error(Egreg);
return n;
}