summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2012-10-09 17:30:16 +0800
committerGerrit <chrome-bot@google.com>2012-11-04 20:27:57 -0800
commit25bbb6b5dec3e0eb9672e6d3e0acf032f9e8d8d1 (patch)
tree40a23648aaea55d7d3f28897d88504ea7d155a14
parent4f410f5468c1ce813450485753ae6f77bca8b7cd (diff)
downloadchrome-ec-25bbb6b5dec3e0eb9672e6d3e0acf032f9e8d8d1.tar.gz
More supports for A20 enable/disable
Add i8042 output port commands (0xf0-0xff), I8042_ENABLE_A20 and I8042_DISABLE_A20. BUG=chrome-os-partner:13119, BRANCH=None TEST=Tested on W7 installer. No KB error shown on EC console. Change-Id: I9ad1fd7baa10683ef18ccf13faf09dc0cefcca0a Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/34994 Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
-rw-r--r--chip/lm4/lpc.c7
-rw-r--r--common/keyboard.c31
-rw-r--r--include/i8042_protocol.h6
-rw-r--r--include/lpc.h3
4 files changed, 45 insertions, 2 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index 2ca762481d..8b8f0a2740 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -214,6 +214,13 @@ int lpc_keyboard_has_char(void)
return (LM4_LPC_ST(LPC_CH_KEYBOARD) & LM4_LPC_ST_TOH) ? 1 : 0;
}
+/* Return true if the FRMH is set */
+int lpc_keyboard_input_pending(void)
+{
+ return (LM4_LPC_ST(LPC_CH_KEYBOARD) & LM4_LPC_ST_FRMH) ? 1 : 0;
+}
+
+/* Put a char to host buffer and send IRQ if specified. */
void lpc_keyboard_put_char(uint8_t chr, int send_irq)
{
LPC_POOL_KEYBOARD[1] = chr;
diff --git a/common/keyboard.c b/common/keyboard.c
index f71842d7dd..2a68986a23 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -62,6 +62,7 @@ static uint8_t controller_ram[0x20] = {
I8042_XLATE | I8042_AUX_DIS | I8042_KBD_DIS,
/* 0x01 - 0x1f are controller RAM */
};
+static uint8_t A20_status;
static int power_button_pressed = 0;
static void keyboard_special(uint16_t k);
@@ -355,6 +356,7 @@ static enum {
STATE_EX_SETLEDS_1, /* expect 2-byte parameter coming */
STATE_EX_SETLEDS_2,
STATE_WRITE_CMD_BYTE,
+ STATE_WRITE_OUTPUT_PORT,
STATE_ECHO_MOUSE,
STATE_SETREP,
STATE_SEND_TO_MOUSE,
@@ -409,6 +411,13 @@ int handle_keyboard_data(uint8_t data, uint8_t *output)
data_port_state = STATE_NORMAL;
break;
+ case STATE_WRITE_OUTPUT_PORT:
+ CPRINTF5("[%T KB eaten by STATE_WRITE_OUTPUT_PORT: 0x%02x]\n",
+ data);
+ A20_status = (data & (1 << 1)) ? 1 : 0;
+ data_port_state = STATE_NORMAL;
+ break;
+
case STATE_ECHO_MOUSE:
CPRINTF5("[%T KB eaten by STATE_ECHO_MOUSE: 0x%02x]\n", data);
output[out_len++] = data;
@@ -559,6 +568,18 @@ int handle_keyboard_command(uint8_t command, uint8_t *output)
update_ctl_ram(0, read_ctl_ram(0) & ~I8042_KBD_DIS);
break;
+ case I8042_READ_OUTPUT_PORT:
+ output[out_len++] =
+ (lpc_keyboard_input_pending() ? (1 << 5) : 0) |
+ (lpc_keyboard_has_char() ? (1 << 4) : 0) |
+ (A20_status ? (1 << 1) : 0) |
+ 1; /* Main processor in normal mode */
+ break;
+
+ case I8042_WRITE_OUTPUT_PORT:
+ data_port_state = STATE_WRITE_OUTPUT_PORT;
+ break;
+
case I8042_RESET_SELF_TEST:
output[out_len++] = 0x55; /* Self test success */
break;
@@ -599,9 +620,17 @@ int handle_keyboard_command(uint8_t command, uint8_t *output)
command <= I8042_WRITE_CTL_RAM_END) {
data_port_state = STATE_WRITE_CMD_BYTE;
controller_ram_address = command - 0x60;
+ } else if (command == I8042_DISABLE_A20) {
+ A20_status = 0;
+ } else if (command == I8042_ENABLE_A20) {
+ A20_status = 1;
} else if (command >= I8042_PULSE_START &&
command <= I8042_PULSE_END) {
- /* Pulse Output Bit. Not implemented. Ignore it. */
+ /* Pulse Output Bits,
+ * b0=0 to reset CPU, see I8042_SYSTEM_RESET above
+ * b1=0 to disable A20 line
+ */
+ A20_status = command & (1 << 1) ? 1 : 0;
} else {
CPRINTF("[%T KB unsupported cmd: 0x%02x]\n", command);
reset_rate_and_delay();
diff --git a/include/i8042_protocol.h b/include/i8042_protocol.h
index 961d3e337c..eecdafc476 100644
--- a/include/i8042_protocol.h
+++ b/include/i8042_protocol.h
@@ -55,11 +55,15 @@
#define I8042_TEST_KB_PORT 0xab
#define I8042_DIS_KB 0xad
#define I8042_ENA_KB 0xae
+#define I8042_READ_OUTPUT_PORT 0xd0
+#define I8042_WRITE_OUTPUT_PORT 0xd1
#define I8042_ECHO_MOUSE 0xd3 /* expect a byte on port 0x60 */
#define I8042_SEND_TO_MOUSE 0xd4 /* expect a byte on port 0x60 */
+#define I8042_DISABLE_A20 0xdd
+#define I8042_ENABLE_A20 0xdf
#define I8042_PULSE_START 0xf0
-#define I8042_PULSE_END 0xfd
#define I8042_SYSTEM_RESET 0xfe
+#define I8042_PULSE_END 0xff
/* port 0x60 return value */
#define I8042_RET_BAT 0xaa
diff --git a/include/lpc.h b/include/lpc.h
index 3dd39a105e..9ecef5027b 100644
--- a/include/lpc.h
+++ b/include/lpc.h
@@ -23,6 +23,9 @@ uint8_t *lpc_get_memmap_range(void);
*/
int lpc_keyboard_has_char(void);
+/* Return true if the FRMH is still set */
+int lpc_keyboard_input_pending(void);
+
/**
* Send a byte to host via keyboard port 0x60.
*