From cb9328b9a1d6af5d1d27524bf8e1ccfeac0d7471 Mon Sep 17 00:00:00 2001 From: yokota Date: Mon, 10 Jan 2000 08:52:32 +0000 Subject: Obtain the initial key repeat rate setting via BIOS in i386 if possible. --- sys/dev/atkbdc/atkbd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'sys/dev/atkbdc/atkbd.c') diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c index 9d15fc4..4280da6 100644 --- a/sys/dev/atkbdc/atkbd.c +++ b/sys/dev/atkbdc/atkbd.c @@ -39,6 +39,16 @@ #include #include +#ifdef __i386__ +#include +#include +#include +#include + +#include +#include +#endif /* __i386__ */ + #include #include #include @@ -214,6 +224,7 @@ keyboard_switch_t atkbdsw = { KEYBOARD_DRIVER(atkbd, atkbdsw, atkbd_configure); /* local functions */ +static int get_typematic(keyboard_t *kbd); static int setup_kbd_port(KBDC kbdc, int port, int intr); static int get_kbd_echo(KBDC kbdc); static int probe_keyboard(KBDC kbdc, int flags); @@ -323,6 +334,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) accentmap_t *accmap; fkeytab_t *fkeymap; int fkeymap_size; + int delay[2]; int *data = (int *)arg; /* XXX */ @@ -406,6 +418,10 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) return ENXIO; atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); + get_typematic(kbd); + delay[0] = kbd->kb_delay1; + delay[1] = kbd->kb_delay2; + atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); KBD_INIT_DONE(kbd); } if (!KBD_IS_CONFIGURED(kbd)) { @@ -430,6 +446,7 @@ static int atkbd_intr(keyboard_t *kbd, void *arg) { atkbd_state_t *state; + int delay[2]; int c; if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { @@ -451,6 +468,10 @@ atkbd_intr(keyboard_t *kbd, void *arg) init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config); atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); + get_typematic(kbd); + delay[0] = kbd->kb_delay1; + delay[1] = kbd->kb_delay2; + atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); KBD_FOUND_DEVICE(kbd); } } @@ -974,6 +995,39 @@ atkbd_poll(keyboard_t *kbd, int on) /* local functions */ static int +get_typematic(keyboard_t *kbd) +{ +#ifdef __i386__ + /* + * Only some systems allow us to retrieve the keyboard repeat + * rate previously set via the BIOS... + */ + struct vm86frame vmf; + u_int32_t p; + + bzero(&vmf, sizeof(vmf)); + vmf.vmf_ax = 0xc000; + vm86_intcall(0x15, &vmf); + if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah) + return ENODEV; + p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx); + if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */ + return ENODEV; + vmf.vmf_ax = 0x0900; + vm86_intcall(0x16, &vmf); + if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */ + return ENODEV; + vmf.vmf_ax = 0x0306; + vm86_intcall(0x16, &vmf); + kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5); + kbd->kb_delay2 = typematic_rate(vmf.vmf_bl); + return 0; +#else + return ENODEV; +#endif /* __i386__ */ +} + +static int setup_kbd_port(KBDC kbdc, int port, int intr) { if (!set_controller_command_byte(kbdc, -- cgit v1.1