mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
The phenomenon is that there is a char on-hold in port 0x60 and the kernel never picks it up. Hence the keyboard cannnot be recognized after resume. It comes from multiple reasons: 1. The command I8042_CMD_RESET_BAT(0xff) and I8042_CMD_ENABLE(0xf4) didn't clean the buffer. 2. clean_underlying_buffer() has clean the queue, but forgot to clean the TOH (TO Host). Add keyboard_clean_buffer() to clean the TOH (To Host). 3. When KB interrupt is just enabled, the IRQ didn't sent if there is a char queued in buffer already. keyboard_resume_interrupt() solves this. 4. Not all keyboard reset should reset the buffer. Only the enable/disble of controller RAM should NOT reset buffer. Other enable/disable should clean the buffer. 5. i8042 commands (those commands to port 0x64) should NOT return ACK even the parameter byte(s) goes to port 0x60. 6. Keyboard was disabled by kernel, but key stroke still sent to host (this needs the BIOS to fix). Also fix the minor issues: 1. I8042_CMD_RESEND should not return I8042_RET_ACK. 2. I8042_DIS_KB/I8042_ENA_KB should effect the controller RAM content. 3. only send out the scan code when keyboard is enabled. 4. add kblog command for future debug (disabled by default because it neeeds 1KB of memory). Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> BUG=chrome-os-partner:9525 TEST=tested on link. Start from S0. 1. Run powerd_suspend. 2. Expect system is in S3. 3. Press any key to wake up system. 4. Expect system is up and keyboard is working. 5. repeat for 20+ times. Change-Id: I1c48822687d7c1f7ef0e8d8bca54bf9b05fd785f
114 lines
3.3 KiB
C
114 lines
3.3 KiB
C
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* The functions implemented by keyboard component of EC core.
|
|
*/
|
|
|
|
#ifndef __INCLUDE_KEYBOARD_H
|
|
#define __INCLUDE_KEYBOARD_H
|
|
|
|
#include "common.h"
|
|
|
|
/***************************************************************************/
|
|
/* Functions exported by common/keyboard.c.
|
|
*/
|
|
|
|
#define MAX_SCAN_CODE_LEN 4
|
|
|
|
#define MAX_KBLOG 512
|
|
|
|
enum scancode_set_list {
|
|
SCANCODE_GET_SET = 0,
|
|
SCANCODE_SET_1,
|
|
SCANCODE_SET_2,
|
|
SCANCODE_SET_3,
|
|
SCANCODE_MAX = SCANCODE_SET_3,
|
|
};
|
|
|
|
|
|
/* Called by keyboard scan code once any key state change (after de-bounce),
|
|
*
|
|
* This function will look up matrix table and convert scancode host.
|
|
*/
|
|
void keyboard_state_changed(int row, int col, int is_pressed);
|
|
|
|
|
|
/* Handle the port 0x60 writes from host.
|
|
*
|
|
* This functions returns the number of bytes stored in *output buffer.
|
|
*/
|
|
int handle_keyboard_data(uint8_t data, uint8_t *output);
|
|
|
|
/* Handle the port 0x64 writes from host.
|
|
*
|
|
* This functions returns the number of bytes stored in *output buffer.
|
|
* BUT theose bytes will appear at port 0x60.
|
|
*/
|
|
int handle_keyboard_command(uint8_t command, uint8_t *output);
|
|
|
|
|
|
/* Send make/break code of power button to host.
|
|
*/
|
|
void keyboard_set_power_button(int pressed);
|
|
|
|
|
|
/* Log the keyboard-related information */
|
|
void kblog_put(char type, uint8_t byte);
|
|
|
|
|
|
/* Register the board-specific keyboard matrix translation function.
|
|
* The callback function accepts col/row and returns the scan code.
|
|
*
|
|
* Note that *scan_code must be at least 4 bytes long to store maximum
|
|
* possible sequence.
|
|
*/
|
|
typedef enum ec_error_list (*keyboard_matrix_callback)(
|
|
int8_t row, int8_t col, int8_t pressed,
|
|
enum scancode_set_list code_set, uint8_t *scan_code, int32_t* len);
|
|
|
|
enum ec_error_list keyboard_matrix_register_callback(
|
|
int8_t row_num, int8_t col_num,
|
|
keyboard_matrix_callback callback);
|
|
|
|
|
|
/***************************************************************************/
|
|
/* Below is the interface with the underlying chip-dependent code.
|
|
*/
|
|
#define MAX_KEYBOARD_MATRIX_ROWS 8
|
|
#define MAX_KEYBOARD_MATRIX_COLS 16
|
|
|
|
typedef void (*keyboard_callback)(int row, int col, int is_pressed);
|
|
|
|
/* Registers a callback function to underlayer EC lib. So that any key state
|
|
* change would notify the upper EC main code.
|
|
*
|
|
* Note that passing NULL removes any previously registered callback.
|
|
*/
|
|
enum ec_error_list keyboard_register_callback(keyboard_callback cb);
|
|
|
|
/* Asks the underlayer EC lib what keys are pressed right now.
|
|
*
|
|
* Sets bit_array to a debounced array of which keys are currently pressed,
|
|
* where a 1-bit means the key is pressed. For example, if only row=2 col=3
|
|
* is pressed, it would set bit_array to {0, 0, 0x08, 0, ...}
|
|
*
|
|
* bit_array must be at least MAX_KEYBOARD_MATRIX_COLS bytes long.
|
|
*/
|
|
enum ec_error_list keyboard_get_state(uint8_t *bit_array);
|
|
|
|
/* Returns true if the to-host-buffer is non-empty. */
|
|
int keyboard_has_char(void);
|
|
|
|
/* Sends a char to host and triggers IRQ if specified. */
|
|
void keyboard_put_char(uint8_t chr, int send_irq);
|
|
|
|
/* Clears the keyboard buffer to host. */
|
|
void keyboard_clear_buffer(void);
|
|
|
|
/* Host just resumes the interrupt. Sends an interrupt if buffer is non-empty.
|
|
*/
|
|
void keyboard_resume_interrupt(void);
|
|
|
|
#endif /* __INCLUDE_KEYBOARD_H */
|