ref: 90143609212ed4500409a64d26f6b12d097b13ed
parent: 47e3c088c90944e49041c8b210dd7169479738da
author: Sigrid <[email protected]>
date: Sat Mar 28 11:37:48 EDT 2020
kbd: add "repeat" file to set typematic repeat rate/delay on PS/2 keyboards
--- a/sys/man/3/kbd
+++ b/sys/man/3/kbd
@@ -7,6 +7,7 @@
.B /dev/scancode
.B /dev/leds
+.B /dev/repeat
.fi
.SH DESCRIPTION
.PP
@@ -13,9 +14,10 @@
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,13 +31,26 @@
.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)
--- a/sys/src/9/pc/devkbd.c
+++ b/sys/src/9/pc/devkbd.c
@@ -40,6 +40,7 @@
Qdir,
Qscancode,
Qleds,
+ Qrepeat,
};
static Dirtab kbdtab[] = {
@@ -46,6 +47,7 @@
".", {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 @@
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,9 +381,6 @@
{
char tmp[8+1], *p;
- if(c->qid.path != Qleds)
- error(Egreg);
-
p = tmp + n;
if(n >= sizeof(tmp))
p = tmp + sizeof(tmp)-1;
@@ -366,7 +387,12 @@
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;
}