lk201_selftest( int unit) { int messg[4], sl; spl_t s; sl = lk201_softc[unit]->sl_unit; s = spltty(); (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_REQ_ID); delay(10000);/* arbitrary */ messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); splx(s); printf("( lk201 id %x.%x", messg[0], messg[1]); s = spltty(); (*console_putc)(sl, SCREEN_LINE_KEYBOARD, LK_CMD_POWER_UP); /* cannot do this, waiting too long might cause receiver overruns */ /* delay(80000);/* spec says 70 msecs or less */ messg[0] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); messg[1] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); messg[2] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); messg[3] = (*console_getc)(sl, SCREEN_LINE_KEYBOARD, TRUE, TRUE); splx(s); printf(", self-test "); if (messg[0] != 0x01 || messg[1] || messg[2] || messg[3]) printf("bad [%x %x %x %x]", messg[0], messg[1], messg[2], messg[3]); else printf("ok )"); lk201_reset(unit); }
static void lk201_rx_char(unsigned char ch, unsigned char fl) { static unsigned char id[6]; static int id_i; static int shift_state = 0; static int prev_scancode; unsigned char c = scancodeRemap[ch]; if (fl != TTY_NORMAL && fl != TTY_OVERRUN) { printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl); return; } /* Assume this is a power-up ID. */ if (ch == LK_STAT_PWRUP_ID && !id_i) { id[id_i++] = ch; return; } /* Handle the power-up sequence. */ if (id_i) { id[id_i++] = ch; if (id_i == 4) { /* OK, the power-up concluded. */ lk201_report(id); if (id[2] == LK_STAT_PWRUP_OK) lk201_get_id(); else { id_i = 0; printk(KERN_ERR "lk201: keyboard power-up " "error, skipping initialization\n"); } } else if (id_i == 6) { /* We got the ID; report it and start operation. */ id_i = 0; lk201_id(id); lk201_reset(); } return; } /* Everything else is a scancode/status response. */ id_i = 0; switch (ch) { case LK_STAT_RESUME_ERR: case LK_STAT_ERROR: case LK_STAT_INHIBIT_ACK: case LK_STAT_TEST_ACK: case LK_STAT_MODE_KEYDOWN: case LK_STAT_MODE_ACK: break; case LK_KEY_LOCK: shift_state ^= LK_LOCK; handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0); break; case LK_KEY_SHIFT: shift_state ^= LK_SHIFT; handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0); break; case LK_KEY_CTRL: shift_state ^= LK_CTRL; handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0); break; case LK_KEY_COMP: shift_state ^= LK_COMP; handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0); break; case LK_KEY_RELEASE: if (shift_state & LK_SHIFT) handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0); if (shift_state & LK_CTRL) handle_scancode(scancodeRemap[LK_KEY_CTRL], 0); if (shift_state & LK_COMP) handle_scancode(scancodeRemap[LK_KEY_COMP], 0); if (shift_state & LK_LOCK) handle_scancode(scancodeRemap[LK_KEY_LOCK], 0); shift_state = 0; break; case LK_KEY_REPEAT: handle_scancode(prev_scancode, 1); break; default: prev_scancode = c; handle_scancode(c, 1); break; } tasklet_schedule(&keyboard_tasklet); }