ref: 5bb7240ee93111a7c73adaedc0dabfa0caacbe25
parent: 83e20b4df18d539db59c8e1090f77a6565df250e
author: cinap_lenrek <[email protected]>
date: Sat Oct 20 15:57:37 EDT 2018
nusb/kb: work arround broken split transaction on raspi's dwc otg usb controller
--- a/sys/src/cmd/nusb/kb/hid.h
+++ b/sys/src/cmd/nusb/kb/hid.h
@@ -15,6 +15,7 @@
Getreport = 0x01,
Setreport = 0x09,
Getproto = 0x03,
+ Setidle = 0x0a,
Setproto = 0x0b,
/* protocols for SET_PROTO request */
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -299,12 +299,19 @@
static int
setproto(Hiddev *f, int eid)
{
- int id, proto;
+ int proto;
Iface *iface;
iface = f->dev->usb->ep[eid]->iface;
- id = iface->id;
- f->nrep = usbcmd(f->dev, Rd2h|Rstd|Riface, Rgetdesc, Dreport<<8, id,
+
+ /*
+ * DWC OTG controller misses some split transaction inputs.
+ * Set nonzero idle time to return more frequent reports
+ * of keyboard state, to avoid losing key up/down events.
+ */
+ usbcmd(f->dev, Rh2d|Rclass|Riface, Setidle, 8<<8, iface->id, nil, 0);
+
+ f->nrep = usbcmd(f->dev, Rd2h|Rstd|Riface, Rgetdesc, Dreport<<8, iface->id,
f->rep, sizeof(f->rep));
if(f->nrep > 0){
if(debug){
@@ -335,7 +342,7 @@
}
proto = Bootproto;
}
- return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, id, nil, 0);
+ return usbcmd(f->dev, Rh2d|Rclass|Riface, Setproto, proto, iface->id, nil, 0);
}
static int