static void aw_ir_intr(void *arg) { struct aw_ir_softc *sc; uint32_t val; int i, dcnt; unsigned long ir_code; int stat; sc = (struct aw_ir_softc *)arg; /* Read RX interrupt status */ val = READ(sc, AW_IR_RXSTA); /* Clean all pending interrupt statuses */ WRITE(sc, AW_IR_RXSTA, val | AW_IR_RXSTA_CLEARALL); /* When Rx FIFO Data available or Packet end */ if (val & (AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RPEI_EN)) { /* Get available message count in RX FIFO */ dcnt = AW_IR_RXSTA_COUNTER(val); /* Read FIFO */ for (i = 0; i < dcnt; i++) { if (aw_ir_buf_full(sc)) { if (bootverbose) device_printf(sc->dev, "raw buffer full\n"); break; } else aw_ir_buf_write(sc, aw_ir_read_data(sc)); } } if (val & AW_IR_RXINT_RPEI_EN) { /* RX Packet end */ if (bootverbose) device_printf(sc->dev, "RX Packet end\n"); ir_code = aw_ir_decode_packets(sc); stat = aw_ir_validate_code(ir_code); if (stat == 0) { evdev_push_event(sc->sc_evdev, EV_MSC, MSC_SCAN, ir_code); evdev_sync(sc->sc_evdev); } if (bootverbose) { device_printf(sc->dev, "Final IR code: %lx\n", ir_code); device_printf(sc->dev, "IR code status: %d\n", stat); } sc->dcnt = 0; } if (val & AW_IR_RXINT_ROI_EN) { /* RX FIFO overflow */ if (bootverbose) device_printf(sc->dev, "RX FIFO overflow\n"); /* Flush raw buffer */ aw_ir_buf_reset(sc); } }
/* read char from the keyboard */ static u_int atkbd_read_char(keyboard_t *kbd, int wait) { atkbd_state_t *state; u_int action; int scancode; int keycode; state = (atkbd_state_t *)kbd->kb_data; next_code: /* do we have a composed char to return? */ if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) { action = state->ks_composed_char; state->ks_composed_char = 0; if (action > UCHAR_MAX) return ERRKEY; return action; } /* see if there is something in the keyboard port */ if (wait) { do { scancode = read_kbd_data(state->kbdc); } while (scancode == -1); } else { scancode = read_kbd_data_no_wait(state->kbdc); if (scancode == -1) return NOKEY; } ++kbd->kb_count; #if KBDIO_DEBUG >= 10 printf("atkbd_read_char(): scancode:0x%x\n", scancode); #endif #ifdef EVDEV_SUPPORT /* push evdev event */ if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD && state->ks_evdev != NULL) { keycode = evdev_scancode2key(&state->ks_evdev_state, scancode); if (keycode != KEY_RESERVED) { evdev_push_event(state->ks_evdev, EV_KEY, (uint16_t)keycode, scancode & 0x80 ? 0 : 1); evdev_sync(state->ks_evdev); } } #endif /* return the byte as is for the K_RAW mode */ if (state->ks_mode == K_RAW) return scancode; /* translate the scan code into a keycode */ keycode = scancode & 0x7F; switch (state->ks_prefix) { case 0x00: /* normal scancode */ switch(scancode) { case 0xB8: /* left alt (compose key) released */ if (state->ks_flags & COMPOSE) { state->ks_flags &= ~COMPOSE; if (state->ks_composed_char > UCHAR_MAX) state->ks_composed_char = 0; } break; case 0x38: /* left alt (compose key) pressed */ if (!(state->ks_flags & COMPOSE)) { state->ks_flags |= COMPOSE; state->ks_composed_char = 0; } break; case 0xE0: case 0xE1: state->ks_prefix = scancode; goto next_code; } break; case 0xE0: /* 0xE0 prefix */ state->ks_prefix = 0; switch (keycode) { case 0x1C: /* right enter key */ keycode = 0x59; break; case 0x1D: /* right ctrl key */ keycode = 0x5A; break; case 0x35: /* keypad divide key */ keycode = 0x5B; break; case 0x37: /* print scrn key */ keycode = 0x5C; break; case 0x38: /* right alt key (alt gr) */ keycode = 0x5D; break; case 0x46: /* ctrl-pause/break on AT 101 (see below) */ keycode = 0x68; break; case 0x47: /* grey home key */ keycode = 0x5E; break; case 0x48: /* grey up arrow key */ keycode = 0x5F; break; case 0x49: /* grey page up key */ keycode = 0x60; break; case 0x4B: /* grey left arrow key */ keycode = 0x61; break; case 0x4D: /* grey right arrow key */ keycode = 0x62; break; case 0x4F: /* grey end key */ keycode = 0x63; break; case 0x50: /* grey down arrow key */ keycode = 0x64; break; case 0x51: /* grey page down key */ keycode = 0x65; break; case 0x52: /* grey insert key */ keycode = 0x66; break; case 0x53: /* grey delete key */ keycode = 0x67; break; /* the following 3 are only used on the MS "Natural" keyboard */ case 0x5b: /* left Window key */ keycode = 0x69; break; case 0x5c: /* right Window key */ keycode = 0x6a; break; case 0x5d: /* menu key */ keycode = 0x6b; break; case 0x5e: /* power key */ keycode = 0x6d; break; case 0x5f: /* sleep key */ keycode = 0x6e; break; case 0x63: /* wake key */ keycode = 0x6f; break; default: /* ignore everything else */ goto next_code; } break; case 0xE1: /* 0xE1 prefix */ /* * The pause/break key on the 101 keyboard produces: * E1-1D-45 E1-9D-C5 * Ctrl-pause/break produces: * E0-46 E0-C6 (See above.) */ state->ks_prefix = 0; if (keycode == 0x1D) state->ks_prefix = 0x1D; goto next_code; /* NOT REACHED */ case 0x1D: /* pause / break */ state->ks_prefix = 0; if (keycode != 0x45) goto next_code; keycode = 0x68; break; } if (kbd->kb_type == KB_84) { switch (keycode) { case 0x37: /* *(numpad)/print screen */ if (state->ks_flags & SHIFTS) keycode = 0x5c; /* print screen */ break; case 0x45: /* num lock/pause */ if (state->ks_flags & CTLS) keycode = 0x68; /* pause */ break; case 0x46: /* scroll lock/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } } else if (kbd->kb_type == KB_101) { switch (keycode) { case 0x5c: /* print screen */ if (state->ks_flags & ALTS) keycode = 0x54; /* sysrq */ break; case 0x68: /* pause/break */ if (state->ks_flags & CTLS) keycode = 0x6c; /* break */ break; } } /* return the key code in the K_CODE mode */ if (state->ks_mode == K_CODE) return (keycode | (scancode & 0x80)); /* compose a character code */ if (state->ks_flags & COMPOSE) { switch (keycode | (scancode & 0x80)) { /* key pressed, process it */ case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x40; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x47; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ state->ks_composed_char *= 10; state->ks_composed_char += keycode - 0x4E; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; case 0x52: /* keypad 0 */ state->ks_composed_char *= 10; if (state->ks_composed_char > UCHAR_MAX) return ERRKEY; goto next_code; /* key released, no interest here */ case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ case 0xD2: /* keypad 0 */ goto next_code; case 0x38: /* left alt key */ break; default: if (state->ks_composed_char > 0) { state->ks_flags &= ~COMPOSE; state->ks_composed_char = 0; return ERRKEY; } break; } } /* keycode to key action */ action = genkbd_keyaction(kbd, keycode, scancode & 0x80, &state->ks_state, &state->ks_accents); if (action == NOKEY) goto next_code; else return action; }