summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/chell/board.c19
-rw-r--r--board/chell/board.h6
-rw-r--r--chip/mec1322/keyboard_raw.c68
-rw-r--r--common/keyboard_scan.c24
-rw-r--r--include/config.h3
-rw-r--r--include/ec_commands.h7
-rw-r--r--include/keyboard_raw.h7
-rw-r--r--util/ectool.c21
8 files changed, 155 insertions, 0 deletions
diff --git a/board/chell/board.c b/board/chell/board.c
index 62701a36b6..dec82b4f1b 100644
--- a/board/chell/board.c
+++ b/board/chell/board.c
@@ -133,6 +133,25 @@ const enum gpio_signal hibernate_wake_pins[] = {
};
const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
+#ifdef CONFIG_KEYBOARD_FACTORY_TEST
+/*
+ * We have total 28 pins for keyboard connecter, {-1, -1} mean
+ * the N/A pin that don't consider it and reserve index 0 area
+ * that we don't have pin 0.
+ */
+const int keyboard_factory_scan_pins[][2] = {
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},
+ {12, 6}, {4, 3}, {4, 2}, {0, 2}, {14, 2},
+ {4, 0}, {0, 0}, {-1, -1}, {3, 2}, {10, 3},
+ {10, 0}, {12, 5}, {-1, -1}, {10, 2}, {-1, -1},
+ {0, 1}, {10, 4}, {-1, -1}, {-1, -1}, {0, 4},
+ {10, 7}, {10, 6}, {0, 3}, {0, 5},
+};
+
+const int keyboard_factory_scan_pins_used =
+ ARRAY_SIZE(keyboard_factory_scan_pins);
+#endif
+
struct pi3usb9281_config pi3usb9281_chips[] = {
{
.i2c_port = I2C_PORT_USB_CHARGER_1,
diff --git a/board/chell/board.h b/board/chell/board.h
index b28e720bdb..1f735d155e 100644
--- a/board/chell/board.h
+++ b/board/chell/board.h
@@ -48,6 +48,7 @@
#define CONFIG_I2C_MASTER
#define CONFIG_KEYBOARD_PROTOCOL_8042
#define CONFIG_KEYBOARD_COL2_INVERTED
+#define CONFIG_KEYBOARD_FACTORY_TEST
#define CONFIG_LED_COMMON
#define CONFIG_LID_SWITCH
#define CONFIG_LOW_POWER_IDLE
@@ -205,6 +206,11 @@ enum temp_sensor_id {
/* Try to negotiate to 20V since i2c noise problems should be fixed. */
#define PD_MAX_VOLTAGE_MV 20000
+#ifdef CONFIG_KEYBOARD_FACTORY_TEST
+extern const int keyboard_factory_scan_pins[][2];
+extern const int keyboard_factory_scan_pins_used;
+#endif
+
/* Reset PD MCU */
void board_reset_pd_mcu(void);
diff --git a/chip/mec1322/keyboard_raw.c b/chip/mec1322/keyboard_raw.c
index 8569472682..729ab9bda0 100644
--- a/chip/mec1322/keyboard_raw.c
+++ b/chip/mec1322/keyboard_raw.c
@@ -81,3 +81,71 @@ void keyboard_raw_interrupt(void)
task_wake(TASK_ID_KEYSCAN);
}
DECLARE_IRQ(MEC1322_IRQ_KSC_INT, keyboard_raw_interrupt, 1);
+
+#ifdef CONFIG_KEYBOARD_FACTORY_TEST
+
+/* Run keyboard factory testing, scan out KSO/KSI if any shorted. */
+int keyboard_factory_test_scan(void)
+{
+ int i, j;
+ uint16_t shorted = 0;
+ uint32_t port, id, val;
+
+ /* Disable keyboard scan while testing */
+ keyboard_scan_enable(0, KB_SCAN_DISABLE_LID_CLOSED);
+
+ /* Set all of KSO/KSI pins to internal pull-up and input */
+ for (i = 0; i < keyboard_factory_scan_pins_used; i++) {
+
+ if (keyboard_factory_scan_pins[i][0] < 0)
+ continue;
+
+ port = keyboard_factory_scan_pins[i][0];
+ id = keyboard_factory_scan_pins[i][1];
+
+ gpio_set_alternate_function(port, 1 << id, -1);
+ gpio_set_flags_by_mask(port, 1 << id,
+ GPIO_INPUT | GPIO_PULL_UP);
+ }
+
+ /*
+ * Set start pin to output low, then check other pins
+ * going to low level, it indicate the two pins are shorted.
+ */
+ for (i = 0; i < keyboard_factory_scan_pins_used; i++) {
+
+ if (keyboard_factory_scan_pins[i][0] < 0)
+ continue;
+
+ port = keyboard_factory_scan_pins[i][0];
+ id = keyboard_factory_scan_pins[i][1];
+
+ gpio_set_flags_by_mask(port, 1 << id, GPIO_OUT_LOW);
+
+ for (j = 0; j < i; j++) {
+
+ if (keyboard_factory_scan_pins[j][0] < 0)
+ continue;
+
+ /*
+ * Get gpio pin control register,
+ * bit 24 indicate GPIO input from the pad.
+ */
+ val = MEC1322_GPIO_CTL(keyboard_factory_scan_pins[j][0],
+ keyboard_factory_scan_pins[j][1]);
+
+ if ((val & (1 << 24)) == 0) {
+ shorted = i << 8 | j;
+ goto done;
+ }
+ }
+ gpio_set_flags_by_mask(port, 1 << id,
+ GPIO_INPUT | GPIO_PULL_UP);
+ }
+done:
+ gpio_config_module(MODULE_KEYBOARD_SCAN, 1);
+ keyboard_scan_enable(1, KB_SCAN_DISABLE_LID_CLOSED);
+
+ return shorted;
+}
+#endif
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c
index cad5bb559a..cf046b86e4 100644
--- a/common/keyboard_scan.c
+++ b/common/keyboard_scan.c
@@ -748,6 +748,30 @@ DECLARE_HOST_COMMAND(EC_CMD_MKBP_SIMULATE_KEY,
mkbp_command_simulate_key,
EC_VER_MASK(0));
+#ifdef CONFIG_KEYBOARD_FACTORY_TEST
+static int keyboard_factory_test(struct host_cmd_handler_args *args)
+{
+ struct ec_response_keyboard_factory_test *r = args->response;
+
+ /* Only available on unlocked systems */
+ if (system_is_locked())
+ return EC_RES_ACCESS_DENIED;
+
+ if (keyboard_factory_scan_pins_used == 0)
+ return EC_RES_INVALID_COMMAND;
+
+ r->shorted = keyboard_factory_test_scan();
+
+ args->response_size = sizeof(*r);
+
+ return EC_RES_SUCCESS;
+}
+
+DECLARE_HOST_COMMAND(EC_CMD_KEYBOARD_FACTORY_TEST,
+ keyboard_factory_test,
+ EC_VER_MASK(0));
+#endif
+
/*****************************************************************************/
/* Console commands */
#ifdef CONFIG_CMD_KEYBOARD
diff --git a/include/config.h b/include/config.h
index a126055be8..28363da4eb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1209,6 +1209,9 @@
/* Compile code for MKBP keyboard protocol */
#undef CONFIG_KEYBOARD_PROTOCOL_MKBP
+/* Support keyboard factory test scanning */
+#undef CONFIG_KEYBOARD_FACTORY_TEST
+
/*
* Keyboard config (struct keyboard_scan_config) is in board.c. If this is
* not defined, default values from common/keyboard_scan.c will be used.
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 9434a5df45..a205878bec 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2481,6 +2481,13 @@ struct ec_response_get_next_event {
union ec_response_get_next_data data;
} __packed;
+/* Run keyboard factory test scanning */
+#define EC_CMD_KEYBOARD_FACTORY_TEST 0x68
+
+struct ec_response_keyboard_factory_test {
+ uint16_t shorted; /* Keyboard pins are shorted */
+} __packed;
+
/*****************************************************************************/
/* Temperature sensor commands */
diff --git a/include/keyboard_raw.h b/include/keyboard_raw.h
index 8591700b47..db13852635 100644
--- a/include/keyboard_raw.h
+++ b/include/keyboard_raw.h
@@ -71,4 +71,11 @@ void keyboard_raw_gpio_interrupt(enum gpio_signal signal);
static inline void keyboard_raw_gpio_interrupt(enum gpio_signal signal) { }
#endif /* !HAS_TASK_KEYSCAN */
+/**
+ * Run keyboard factory test scanning.
+ *
+ * @return non-zero if keyboard pins are shorted.
+ */
+int keyboard_factory_test_scan(void);
+
#endif /* __CROS_EC_KEYBOARD_RAW_H */
diff --git a/util/ectool.c b/util/ectool.c
index d21bb99fe5..59793e21d6 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -121,6 +121,8 @@ const char help_str[] =
" Set the delay before going into hibernation\n"
" kbpress\n"
" Simulate key press\n"
+ " kbfactorytest\n"
+ " Scan out keyboard if any pins are shorted\n"
" i2cread\n"
" Read I2C bus\n"
" i2cwrite\n"
@@ -4208,6 +4210,24 @@ int cmd_kbpress(int argc, char *argv[])
return 0;
}
+int cmd_keyboard_factory_test(int argc, char *argv[])
+{
+ struct ec_response_keyboard_factory_test r;
+ int rv;
+
+ rv = ec_command(EC_CMD_KEYBOARD_FACTORY_TEST, 0,
+ NULL, 0, &r, sizeof(r));
+ if (rv < 0)
+ return rv;
+
+ if (r.shorted != 0)
+ printf("Keyboard %d and %d pin are shorted.\n",
+ r.shorted & 0x00ff, r.shorted >> 8);
+ else
+ printf("Keyboard factory test passed.\n");
+
+ return 0;
+}
static void print_panic_reg(int regnum, const uint32_t *regs, int index)
{
@@ -6564,6 +6584,7 @@ const struct command commands[] = {
{"lightbar", cmd_lightbar},
{"keyconfig", cmd_keyconfig},
{"keyscan", cmd_keyscan},
+ {"kbfactorytest", cmd_keyboard_factory_test},
{"motionsense", cmd_motionsense},
{"nextevent", cmd_next_event},
{"panicinfo", cmd_panic_info},