/******************************************************************************* * * i8042_kbd_init - reset keyboard and init state flags */ int i8042_kbd_init(void) { int keymap, try; char *penv; if (!kbd_controller_present() || board_i8042_skip()) return -1; #ifdef CONFIG_USE_CPCIDVI penv = getenv("console"); if (penv != NULL) { if (strncmp(penv, "serial", 7) == 0) return -1; } #endif /* Init keyboard device (default US layout) */ keymap = KBD_US; penv = getenv("keymap"); if (penv != NULL) { if (strncmp(penv, "de", 3) == 0) keymap = KBD_GER; } for (try = 0; try < KBD_RESET_TRIES; try++) { if (kbd_reset() == 0) { kbd_mapping = keymap; kbd_flags = NORMAL; kbd_state = 0; kbd_led_set(); return 0; } } return -1; } /******************************************************************************* * * i8042_tstc - test if keyboard input is available * option: cursor blinking if called in a loop */ int i8042_tstc(struct stdio_dev *dev) { unsigned char scan_code = 0; #ifdef CONFIG_CONSOLE_CURSOR if (--blinkCount == 0) { cursor_state ^= 1; console_cursor(cursor_state); blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT; udelay(10); } #endif if ((in8(I8042_STATUS_REG) & 0x01) == 0) { return 0; } else { scan_code = in8(I8042_DATA_REG); if (scan_code == 0xfa) return 0; kbd_conv_char(scan_code); if (kbd_input != -1) return 1; } return 0; }
/* i8042_kbd_init - reset keyboard and init state flags */ static int i8042_start(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); struct i8042_kbd_priv *priv = dev_get_priv(dev); struct input_config *input = &uc_priv->input; int keymap, try; char *penv; int ret; if (!kbd_controller_present() || board_i8042_skip()) { debug("i8042 keyboard controller is not present\n"); return -ENOENT; } /* Init keyboard device (default US layout) */ keymap = KBD_US; penv = getenv("keymap"); if (penv != NULL) { if (strncmp(penv, "de", 3) == 0) keymap = KBD_GER; } for (try = 0; kbd_reset(priv->quirks) != 0; try++) { if (try >= KBD_RESET_TRIES) return -1; } ret = input_add_tables(input, keymap == KBD_GER); if (ret) return ret; i8042_kbd_update_leds(dev, NORMAL); debug("%s: started\n", __func__); return 0; } /** * Set up the i8042 keyboard. This is called by the stdio device handler * * We want to do this init when the keyboard is actually used rather than * at start-up, since keyboard input may not currently be selected. * * Once the keyboard starts there will be a period during which we must * wait for the keyboard to init. We do this only when a key is first * read - see kbd_wait_for_fifo_init(). * * @return 0 if ok, -ve on error */ static int i8042_kbd_probe(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); struct i8042_kbd_priv *priv = dev_get_priv(dev); struct stdio_dev *sdev = &uc_priv->sdev; struct input_config *input = &uc_priv->input; int ret; if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "intel,duplicate-por")) priv->quirks |= QUIRK_DUP_POR; /* Register the device. i8042_start() will be called soon */ input->dev = dev; input->read_keys = i8042_kbd_check; input_allow_repeats(input, true); strcpy(sdev->name, "i8042-kbd"); ret = input_stdio_register(sdev); if (ret) { debug("%s: input_stdio_register() failed\n", __func__); return ret; } debug("%s: ready\n", __func__); return 0; } static const struct keyboard_ops i8042_kbd_ops = { .start = i8042_start, .update_leds = i8042_kbd_update_leds, }; static const struct udevice_id i8042_kbd_ids[] = { { .compatible = "intel,i8042-keyboard" }, { } };