- enable f13-24 (but this conflicts with prior usage) - enable led setting. unlike ps/2 this does not change the codes. - catch keys affected by numlock, and correct scan code. - move all key processing to operate on the usb code, not the scan code. - save the correct epid for restarting. Reference: /n/atom/patch/applied/usbkbbits Date: Thu Mar 20 14:44:09 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/usb/kb/kb.c Thu Mar 20 14:42:12 2014 +++ /sys/src/cmd/usb/kb/kb.c Thu Mar 20 14:42:14 2014 @@ -39,6 +39,7 @@ Channel* repeatc; Channel* exitc; long nproc; + uint led; }; struct Mouse @@ -50,6 +51,7 @@ { Dev* dev; /* usb device*/ Dev* ep; /* endpoint to get events */ + int eid; /* id of endpoint (not of open ep) */ Kin* in; /* used to send events to kernel */ int idle; /* min time between reports (× 4ms) */ int bootp; /* has associated keyboard */ @@ -98,14 +100,14 @@ [0x20] 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, [0x28] 0x1c, 0x01, 0x0e, 0x0f, 0x39, 0x0c, 0x0d, 0x1a, [0x30] 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34, -[0x38] 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, -[0x40] 0x41, 0x42, 0x43, 0x44, E|0x57, E|0x58, E|0x63, 0x46, +[0x38] 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, /* /, ctl, f1-f6 */ +[0x40] 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, E|0x63, 0x46, /* f7-f10, ... */ [0x48] E|0x77, E|0x52, E|0x47, E|0x49, E|0x53, E|0x4f, E|0x51, E|0x4d, [0x50] E|0x4b, E|0x50, E|0x48, 0x45, 0x35, 0x37, 0x4a, 0x4e, [0x58] 0x1c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, [0x60] 0x48, 0x49, 0x52, 0x53, E|0x56, E|0x7f, E|0x74, E|0x75, -[0x68] E|0x55, E|0x59, E|0x5a, E|0x5b, E|0x5c, E|0x5d, E|0x5e, E|0x5f, -[0x70] E|0x78, E|0x79, E|0x7a, E|0x7b, 0, 0, 0, 0, +[0x68] 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* f13-f20 */ +[0x70] 0x6c, 0x6d, 0x6e, 0x6f, 0, 0, 0, 0, /* f21-f24, */ [0x78] 0, 0, 0, 0, 0, 0, 0, E|0x71, [0x80] E|0x73, E|0x72, 0, 0, 0, E|0x7c, 0, 0, [0x88] 0, 0, 0, 0, 0, 0, 0, 0, @@ -188,7 +190,7 @@ f->ptrvals = ptrbootpvals; r = Rh2d|Rclass|Riface; - dprint(2, "setting boot protocol\n"); + dprint(2, "setting boot protocol %d\n", eid); id = f->dev->usb->ep[eid]->iface->id; nr = usbcmd(f->dev, r, Setproto, Bootproto, id, nil, 0); if(nr < 0) @@ -197,6 +199,20 @@ return nr; } +static int +setled(KDev* f, uint v) +{ + uchar led[1]; + int r, id; + + r = Rh2d|Rclass|Riface; + led[0] = v; + + dprint(2, "led: %.2ux\n", led[0]); + id = f->dev->usb->ep[f->eid]->iface->id; + return usbcmd(f->dev, r, Setreport, Reportout | Ledreport, id, led, 1); +} + static uchar ignoredesc[128]; static int @@ -204,7 +220,7 @@ { int nr, r, id, i; - dprint(2, "setting first config\n"); + dprint(2, "setting first config %d\n", eid); if(desc == nil){ descsz = sizeof ignoredesc; desc = ignoredesc; @@ -253,9 +269,9 @@ if(opendevdata(f->dev, ORDWR) >= 0){ if(f->bootp) /* TODO func pointer */ - setbootproto(f, f->ep->id, nil, 0); + setbootproto(f, f->eid, nil, 0); else - setfirstconfig(f, f->ep->id, nil, 0); + setfirstconfig(f, f->eid, nil, 0); break; } /* else usbd still working... */ @@ -472,14 +488,6 @@ { uchar s[2]; - if(sc == 0x41){ - f->debug += 2; - return; - } - if(sc == 0x42){ - f->debug = 0; - return; - } if(f->debug > 1) fprint(2, "sc: %.4ux\n", sc); if((uchar)sc == 0) @@ -559,6 +567,18 @@ putscan(f, sc | Keyup); } +static Scan +usbtosc(KDev *f, uchar usbcode) +{ + Scan sc; + + sc = sctab[usbcode]; + if((f->led & Lnum) == 0) + if(usbcode >= 0x54 && usbcode <= 0x63) + sc |= SCesc1<<8; + return sc; +} + /* * This routine diffs the state with the last known state * and invents the scan codes that would have been sent @@ -585,7 +605,31 @@ if(buf[i] == obuf[j]) break; if(j == n && buf[i] != 0){ - dk = sctab[buf[i]]; + switch(buf[i]){ + case 0x40: + f->debug += 2; + break; + case 0x41: + f->debug = 0; + break; + case 0x53: + f->led ^= Lnum; + setled(f, f->led); + break; + case 0x47: + f->led ^= Lscroll; + setled(f, f->led); + break; + case 0x39: + // f->led ^= Lcaps; + // setled(f, f->led); + break; + case 0x70: /* f21 */ + f->led ^= Lkana; + setled(f, f->led); + break; + } + dk = usbtosc(f, buf[i]); putscan(f, dk); startrepeat(f, dk); } @@ -598,7 +642,7 @@ if(obuf[i] == buf[j]) break; if(j == n && obuf[i] != 0){ - uk = sctab[obuf[i]]; + uk = usbtosc(f, obuf[i]); putscan(f, uk|Keyup); } } @@ -718,9 +762,10 @@ res = -1; kd->ep = openep(d, ep->id); if(kd->ep == nil){ - fprint(2, "kb: %s: openep %d: %r\n", d->dir, ep->id); + fprint(2, "kb: %s: workep: openep %d: %r\n", d->dir, ep->id); return; } + kd->eid = ep->id; if(in == &kbdin){ /* * DWC OTG controller misses some split transaction inputs. @@ -754,6 +799,9 @@ return; } + kd->led = Lnum; + setled(kd, kd->led); + incref(d); proccreate(f, kd, Stack); } @@ -822,7 +870,7 @@ for(i = 0; i < nelem(ud->ep); i++){ if((ep = ud->ep[i]) == nil) continue; - if(kena && ep->type == Eintr && ep->dir == Ein && + if(kena && ep->type == Eintr && (ep->dir == Ein | ep->dir == Eboth) && ep->iface->csp == KbdCSP){ kd = d->aux = emallocz(sizeof(KDev), 1); kd->accel = 0; @@ -830,7 +878,7 @@ kd->debug = debug; kbstart(d, ep, &kbdin, kbdwork, kd); } - if(pena && ep->type == Eintr && ep->dir == Ein && + if(pena && ep->type == Eintr && (ep->dir == Ein | ep->dir == Eboth) && ep->iface->csp == PtrCSP){ kd = d->aux = emallocz(sizeof(KDev), 1); kd->accel = accel;