Allow regular off-the-shelf keyboards to be overclocked like so-called

"Gamers Keyboards" by adding a tunable, "hw.usb.ukbd.pollrate", which
can fix the polling rate of the attached USB keyboards in the range
1..1000Hz. A similar feature already exists in the USB mouse
driver. Use with care! Might leave you without keyboard input. This
feature is only available when the USB_DEBUG option is set in the
kernel configuration file.

Correct "unit" type to "int" while at it.
This commit is contained in:
Hans Petter Selasky 2013-07-13 22:39:56 +00:00
parent da7d8f2a65
commit 0ccd2fb09e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=253332

View File

@ -92,14 +92,18 @@ __FBSDID("$FreeBSD$");
#ifdef USB_DEBUG
static int ukbd_debug = 0;
static int ukbd_no_leds = 0;
static int ukbd_pollrate = 0;
static SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
static SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB keyboard");
SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
&ukbd_debug, 0, "Debug level");
TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug);
SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RW | CTLFLAG_TUN,
&ukbd_no_leds, 0, "Disables setting of keyboard leds");
TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds);
SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, pollrate, CTLFLAG_RW | CTLFLAG_TUN,
&ukbd_pollrate, 0, "Force this polling rate, 1-1000Hz");
TUNABLE_INT("hw.usb.ukbd.pollrate", &ukbd_pollrate);
#endif
#define UKBD_EMULATE_ATSCANCODE 1
@ -1165,13 +1169,15 @@ ukbd_attach(device_t dev)
{
struct ukbd_softc *sc = device_get_softc(dev);
struct usb_attach_arg *uaa = device_get_ivars(dev);
int32_t unit = device_get_unit(dev);
int unit = device_get_unit(dev);
keyboard_t *kbd = &sc->sc_kbd;
void *hid_ptr = NULL;
usb_error_t err;
uint16_t n;
uint16_t hid_len;
#ifdef USB_DEBUG
int rate;
#endif
UKBD_LOCK_ASSERT();
kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
@ -1272,6 +1278,19 @@ ukbd_attach(device_t dev)
genkbd_diag(kbd, bootverbose);
}
#ifdef USB_DEBUG
/* check for polling rate override */
rate = ukbd_pollrate;
if (rate > 0) {
if (rate > 1000)
rate = 1;
else
rate = 1000 / rate;
/* set new polling interval in ms */
usbd_xfer_set_interval(sc->sc_xfer[UKBD_INTR_DT], rate);
}
#endif
/* start the keyboard */
usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);