From 1af1c74c100e6b72d2570d3f082f82a292a29a0e Mon Sep 17 00:00:00 2001 From: "Vic (Chun-Ju) Yang" Date: Fri, 13 Dec 2013 12:16:33 +0800 Subject: mec1322: i8042 interface This implements i8042 keyboard interface at LPC 0x60/0x64. BUG=chrome-os-partner:21407 TEST=Enable keyboard and keystroke from host ACPI commands. Short KSO pins and KSI pins, and read different key codes from host. BRANCH=None Change-Id: Ie4e5e236bdeefd7e44974f92fcbafab5e4af2b30 Signed-off-by: Vic (Chun-Ju) Yang Reviewed-on: https://chromium-review.googlesource.com/179940 --- chip/mec1322/lpc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ chip/mec1322/registers.h | 11 +++++++++++ 2 files changed, 62 insertions(+) (limited to 'chip') diff --git a/chip/mec1322/lpc.c b/chip/mec1322/lpc.c index 3b47f39a84..4505aaab52 100644 --- a/chip/mec1322/lpc.c +++ b/chip/mec1322/lpc.c @@ -10,6 +10,7 @@ #include "gpio.h" #include "hooks.h" #include "host_command.h" +#include "keyboard_protocol.h" #include "lpc.h" #include "registers.h" #include "task.h" @@ -169,6 +170,15 @@ static void setup_lpc(void) MEC1322_INT_BLK_EN |= 1 << 15; task_enable_irq(MEC1322_IRQ_ACPIEC1_IBF); + /* Set up 8042 interface at 0x60/0x64 */ + MEC1322_LPC_8042_BAR = 0x00608104; + MEC1322_8042_ACT |= 1; + MEC1322_INT_ENABLE(15) |= 1 << 14; + MEC1322_INT_BLK_EN |= 1 << 15; + task_enable_irq(MEC1322_IRQ_8042EM_IBF); + + /* TODO(crosbug.com/p/24107): Route KIRQ to SER_IRQ1 */ + /* Set up EMI module for memory mapped region. * TODO(crosbug.com/p/24107): Use LPC memory transaction for this * when we have updated info of memory BAR @@ -280,6 +290,47 @@ static void acpi_1_interrupt(void) } DECLARE_IRQ(MEC1322_IRQ_ACPIEC1_IBF, acpi_1_interrupt, 1); +#ifdef HAS_TASK_KEYPROTO +static void kb_ibf_interrupt(void) +{ + if (lpc_keyboard_input_pending()) + keyboard_host_write(MEC1322_8042_H2E, + MEC1322_8042_STS & (1 << 3)); + task_wake(TASK_ID_KEYPROTO); +} +DECLARE_IRQ(MEC1322_IRQ_8042EM_IBF, kb_ibf_interrupt, 1); +#endif + +int lpc_keyboard_has_char(void) +{ + return (MEC1322_8042_STS & (1 << 0)) ? 1 : 0; +} + +int lpc_keyboard_input_pending(void) +{ + return (MEC1322_8042_STS & (1 << 1)) ? 1 : 0; +} + +void lpc_keyboard_put_char(uint8_t chr, int send_irq) +{ + MEC1322_8042_E2H = chr; + /* + * TODO(crosbug.com/p/24107): Implement SER_IRQ and handle + * send_irq. + */ +} + +void lpc_keyboard_clear_buffer(void) +{ + volatile char dummy __attribute__((unused)); + dummy = MEC1322_8042_OBF_CLR; +} + +void lpc_keyboard_resume_irq(void) +{ + /* TODO(crosbug.com/p/24107): Implement SER_IRQ */ +} + void lpc_set_host_event_state(uint32_t mask) { if (mask != host_events) { diff --git a/chip/mec1322/registers.h b/chip/mec1322/registers.h index 4972681047..14c1aebfff 100644 --- a/chip/mec1322/registers.h +++ b/chip/mec1322/registers.h @@ -191,6 +191,17 @@ static inline uintptr_t gpio_port_base(int port_id) #define MEC1322_ACPI_EC_OS2EC(x, y) REG8(MEC1322_ACPI_EC_BASE(x) + 0x108 + (y)) +/* 8042 */ +#define MEC1322_8042_BASE 0x400f0400 +#define MEC1322_8042_OBF_CLR REG8(MEC1322_8042_BASE + 0x0) +#define MEC1322_8042_H2E REG8(MEC1322_8042_BASE + 0x100) +#define MEC1322_8042_E2H REG8(MEC1322_8042_BASE + 0x100) +#define MEC1322_8042_STS REG8(MEC1322_8042_BASE + 0x104) +#define MEC1322_8042_KB_CTRL REG8(MEC1322_8042_BASE + 0x108) +#define MEC1322_8042_PCOBF REG8(MEC1322_8042_BASE + 0x114) +#define MEC1322_8042_ACT REG8(MEC1322_8042_BASE + 0x330) + + /* FAN */ #define MEC1322_FAN_BASE 0x4000a000 #define MEC1322_FAN_SETTING REG8(MEC1322_FAN_BASE + 0x0) -- cgit v1.2.1