mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 00:21:46 +00:00
Merge "Keyboard scan must stop driving columns when power button is pressed."
This commit is contained in:
@@ -63,6 +63,8 @@ enum COLUMN_INDEX {
|
||||
|
||||
#define KB_COLS 13
|
||||
|
||||
|
||||
static int enable_scanning = 1;
|
||||
static uint8_t raw_state[KB_COLS];
|
||||
static uint8_t raw_state_at_boot[KB_COLS];
|
||||
static int recovery_key_pressed;
|
||||
@@ -95,6 +97,8 @@ static const uint8_t actual_key_masks[4][KB_COLS] = {
|
||||
static void select_column(int col)
|
||||
{
|
||||
if (col == COLUMN_ASSERT_ALL) {
|
||||
if (!enable_scanning)
|
||||
return;
|
||||
LM4_GPIO_DIR(LM4_GPIO_P) = 0xff;
|
||||
LM4_GPIO_DIR(LM4_GPIO_Q) |= 0x1f;
|
||||
LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0;
|
||||
@@ -102,7 +106,11 @@ static void select_column(int col)
|
||||
} else {
|
||||
LM4_GPIO_DIR(LM4_GPIO_P) = 0;
|
||||
LM4_GPIO_DIR(LM4_GPIO_Q) &= ~0x1f;
|
||||
if (col < 8) {
|
||||
/* Return after the above TRI_STATE_ALL has be run. */
|
||||
if (!enable_scanning)
|
||||
return;
|
||||
|
||||
if (col >= 0 && col < 8) {
|
||||
LM4_GPIO_DIR(LM4_GPIO_P) |= 1 << col;
|
||||
LM4_GPIO_DATA(LM4_GPIO_P, 1 << col) = 0;
|
||||
} else if (col != COLUMN_TRI_STATE_ALL) {
|
||||
@@ -232,7 +240,7 @@ static int check_keys_changed(void)
|
||||
for (i = 0; i < 8; ++i) {
|
||||
uint8_t prev = (raw_state[c] >> i) & 1;
|
||||
uint8_t now = (r >> i) & 1;
|
||||
if (prev != now) {
|
||||
if (prev != now && enable_scanning) {
|
||||
keyboard_state_changed(i, c, now);
|
||||
}
|
||||
}
|
||||
@@ -360,6 +368,7 @@ void keyboard_scan_task(void)
|
||||
|
||||
/* Enable interrupts */
|
||||
task_enable_irq(KB_SCAN_ROW_IRQ);
|
||||
enable_scanning = 1;
|
||||
|
||||
while (1) {
|
||||
wait_for_interrupt();
|
||||
@@ -367,7 +376,7 @@ void keyboard_scan_task(void)
|
||||
|
||||
enter_polling_mode();
|
||||
/* Busy polling keyboard state. */
|
||||
while (1) {
|
||||
while (enable_scanning) {
|
||||
/* sleep for debounce. */
|
||||
usleep(SCAN_LOOP_DELAY);
|
||||
/* Check for keys down */
|
||||
@@ -381,10 +390,10 @@ void keyboard_scan_task(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO: (crosbug.com/p/7484) A race condition here.
|
||||
* If a key state is changed here (before interrupt is
|
||||
* enabled), it will be lost.
|
||||
*/
|
||||
/* Don't continue if the power button is not released yet. */
|
||||
while (!enable_scanning) {
|
||||
usleep(SCAN_LOOP_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,3 +450,21 @@ int keyboard_get_scan(uint8_t **buffp, int max_bytes)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* The actuall implementation is controlling the enable_scanning variable,
|
||||
* then that controls whether select_column() can pull-down columns or not.
|
||||
*/
|
||||
void keyboard_enable_scanning(int enable)
|
||||
{
|
||||
enable_scanning = enable;
|
||||
if (enable) {
|
||||
/* A power button press had tri-stated all columns (see the
|
||||
* 'else' statement below), we need a wake-up to unlock
|
||||
* the task_wait_event() loop after wait_for_interrupt(). */
|
||||
task_wake(TASK_ID_KEYSCAN);
|
||||
} else {
|
||||
select_column(COLUMN_TRI_STATE_ALL);
|
||||
keyboard_clear_underlying_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,6 +200,7 @@ static void power_button_released(uint64_t tnow)
|
||||
tnext_state = tnow;
|
||||
*memmap_switches &= ~EC_SWITCH_POWER_BUTTON_PRESSED;
|
||||
keyboard_set_power_button(0);
|
||||
keyboard_enable_scanning(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -528,6 +529,12 @@ void power_button_interrupt(enum gpio_signal signal)
|
||||
case GPIO_POWER_BUTTONn:
|
||||
/* Reset power button debounce time */
|
||||
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
|
||||
if (get_power_button_pressed()) {
|
||||
/* We want to disable the matrix scan as soon as
|
||||
* possible to reduce the risk of false-reboot triggered
|
||||
* by those keys on the same column with ESC key. */
|
||||
keyboard_enable_scanning(0);
|
||||
}
|
||||
break;
|
||||
case GPIO_PCH_BKLTEN:
|
||||
update_backlight();
|
||||
|
||||
@@ -46,7 +46,7 @@ static int i8042_irq_enabled = 0;
|
||||
|
||||
|
||||
/* Reset all i8042 buffer */
|
||||
void i8042_init()
|
||||
void i8042_flush_buffer()
|
||||
{
|
||||
head_to_buffer = tail_to_buffer = 0;
|
||||
keyboard_clear_buffer();
|
||||
|
||||
@@ -255,9 +255,9 @@ static void reset_rate_and_delay(void)
|
||||
}
|
||||
|
||||
|
||||
static void clear_underlying_buffer(void)
|
||||
void keyboard_clear_underlying_buffer(void)
|
||||
{
|
||||
i8042_init();
|
||||
i8042_flush_buffer();
|
||||
}
|
||||
|
||||
|
||||
@@ -482,25 +482,25 @@ int handle_keyboard_data(uint8_t data, uint8_t *output)
|
||||
case I8042_CMD_ENABLE:
|
||||
output[out_len++] = I8042_RET_ACK;
|
||||
keyboard_enable(1);
|
||||
clear_underlying_buffer();
|
||||
keyboard_clear_underlying_buffer();
|
||||
break;
|
||||
|
||||
case I8042_CMD_RESET_DIS:
|
||||
output[out_len++] = I8042_RET_ACK;
|
||||
keyboard_enable(0);
|
||||
reset_rate_and_delay();
|
||||
clear_underlying_buffer();
|
||||
keyboard_clear_underlying_buffer();
|
||||
break;
|
||||
|
||||
case I8042_CMD_RESET_DEF:
|
||||
output[out_len++] = I8042_RET_ACK;
|
||||
reset_rate_and_delay();
|
||||
clear_underlying_buffer();
|
||||
keyboard_clear_underlying_buffer();
|
||||
break;
|
||||
|
||||
case I8042_CMD_RESET_BAT:
|
||||
reset_rate_and_delay();
|
||||
clear_underlying_buffer();
|
||||
keyboard_clear_underlying_buffer();
|
||||
output[out_len++] = I8042_RET_ACK;
|
||||
output[out_len++] = I8042_RET_BAT;
|
||||
output[out_len++] = I8042_RET_BAT;
|
||||
@@ -613,7 +613,7 @@ int handle_keyboard_command(uint8_t command, uint8_t *output)
|
||||
} else {
|
||||
CPRINTF("[Unsupported cmd: 0x%02x]\n", command);
|
||||
reset_rate_and_delay();
|
||||
clear_underlying_buffer();
|
||||
keyboard_clear_underlying_buffer();
|
||||
output[out_len++] = I8042_RET_NAK;
|
||||
data_port_state = STATE_NORMAL;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
#define I8042_ENIRQ1 (1 << 0)
|
||||
|
||||
|
||||
void i8042_init(void);
|
||||
void i8042_flush_buffer(void);
|
||||
|
||||
|
||||
/* common/i8042.c implements this function, which is called by lpc.c
|
||||
|
||||
@@ -53,6 +53,9 @@ void kblog_put(char type, uint8_t byte);
|
||||
#define MAX_KEYBOARD_MATRIX_ROWS 8
|
||||
#define MAX_KEYBOARD_MATRIX_COLS 16
|
||||
|
||||
/* Clear the keyboard buffer to host. */
|
||||
void keyboard_clear_underlying_buffer(void);
|
||||
|
||||
/* Asks the underlayer EC lib what keys are pressed right now.
|
||||
*
|
||||
* Sets bit_array to a debounced array of which keys are currently pressed,
|
||||
|
||||
@@ -19,4 +19,9 @@ int keyboard_scan_recovery_pressed(void);
|
||||
/* clear any saved keyboard state (empty FIFO, etc) */
|
||||
void keyboard_clear_state(void);
|
||||
|
||||
|
||||
/* Enables/disables keyboard matrix scan. */
|
||||
void keyboard_enable_scanning(int enable);
|
||||
|
||||
|
||||
#endif /* __CROS_KEYBOARD_SCAN_H */
|
||||
|
||||
Reference in New Issue
Block a user