always use older cros protocol. We don't realy need new one

This commit is contained in:
Vladimir Serbinenko committed 2016-02-23 09:42:09 +01:00
1 parent 40562ddf1e
commit 03104c2d98
3 files changed
+4 -673

No files matched your search

+2 -2
View File
@@ -49,7 +49,8 @@ grub_cros_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))
{
struct cros_ec_keyscan scan;
int i, j;
cros_ec_scan_keyboard(&scan);
if (cros_ec_scan_keyboard(&scan) < 0)
return GRUB_TERM_NO_KEY;
for (i = 0; i < CROS_EC_KEYSCAN_COLS; i++)
if (scan.data[i] ^ old_scan.data[i])
for (j = 0; j < CROS_EC_KEYSCAN_ROWS; j++)
@@ -98,7 +99,6 @@ cros_attach(const struct grub_fdtbus_dev *dev __attribute__ ((unused)))
ps2_state.current_set = 1;
ps2_state.at_keyboard_status = 0;
cros_ec_init();
grub_term_register_input ("cros_keyboard", &grub_cros_keyboard_term);
return GRUB_ERR_NONE;
}
+2 -669
View File
@@ -100,21 +100,6 @@ spi_stop (void)
#pragma GCC diagnostic ignored "-Wsign-compare"
typedef int (*SendCommandFunc)(int cmd, int cmd_version, const void *dout,
int dout_len, void *dinp, int din_len);
SendCommandFunc send_command_func;
static struct ec_host_request *proto3_request;
static int proto3_request_size;
static struct ec_host_response *proto3_response;
static int proto3_response_size;
static int max_param_size;
static int passthru_param_size;
static int initialized;
static const uint64_t FramingTimeoutUs = 1000 * 1000;
static const uint8_t EcFramingByte = 0xec;
@@ -244,311 +229,9 @@ enum ec_status {
/*****************************************************************************/
/*
* Value written to legacy command port / prefix byte to indicate protocol
* 3+ structs are being used. Usage is bus-dependent.
*/
#define EC_COMMAND_PROTOCOL_3 0xda
#define EC_HOST_REQUEST_VERSION 3
/* Version 3 request from host */
struct ec_host_request {
/* Struct version (=3)
*
* EC will return EC_RES_INVALID_HEADER if it receives a header with a
* version it doesn't know how to parse.
*/
uint8_t struct_version;
/*
* Checksum of request and data; sum of all bytes including checksum
* should total to 0.
*/
uint8_t checksum;
/* Command code */
uint16_t command;
/* Command version */
uint8_t command_version;
/* Unused byte in current protocol version; set to 0 */
uint8_t reserved;
/* Length of data which follows this header */
uint16_t data_len;
} __packed;
#define EC_HOST_RESPONSE_VERSION 3
/* Version 3 response from EC */
struct ec_host_response {
/* Struct version (=3) */
uint8_t struct_version;
/*
* Checksum of response and data; sum of all bytes including checksum
* should total to 0.
*/
uint8_t checksum;
/* Result code (EC_RES_*) */
uint16_t result;
/* Length of data which follows this header */
uint16_t data_len;
/* Unused bytes in current protocol version; set to 0 */
uint16_t reserved;
} __packed;
/*****************************************************************************/
/*
* Notes on commands:
*
* Each command is an 16-bit command value. Commands which take params or
* return response data specify structs for that data. If no struct is
* specified, the command does not input or output data, respectively.
* Parameter/response length is implicit in the structs. Some underlying
* communication protocols (I2C, SPI) may add length or checksum headers, but
* those are implementation-dependent and not defined here.
*/
/*****************************************************************************/
/* General / test commands */
/*
* Get protocol version, used to deal with non-backward compatible protocol
* changes.
*/
#define EC_CMD_PROTO_VERSION 0x00
struct ec_response_proto_version {
uint32_t version;
} __packed;
/*
* Check EC communcations status (busy). This is needed on i2c/spi but not
* on lpc since it has its own out-of-band busy indicator.
*
* lpc must read the status from the command register. Attempting this on
* lpc will overwrite the args/parameter space and corrupt its data.
*/
#define EC_CMD_GET_COMMS_STATUS 0x09
/* Avoid using ec_status which is for return values */
enum ec_comms_status {
EC_COMMS_STATUS_PROCESSING = 1 << 0, /* Processing cmd */
};
struct ec_response_get_comms_status {
uint32_t flags; /* Mask of enum ec_comms_status */
} __packed;
/* Get prococol information */
#define EC_CMD_GET_PROTOCOL_INFO 0x0b
/* Flags for ec_response_get_protocol_info.flags */
/* EC_RES_IN_PROGRESS may be returned if a command is slow */
#define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0)
struct ec_response_get_protocol_info {
/* Fields which exist if at least protocol version 3 supported */
/* Bitmask of protocol versions supported (1 << n means version n)*/
uint32_t protocol_versions;
/* Maximum request packet size, in bytes */
uint16_t max_request_packet_size;
/* Maximum response packet size, in bytes */
uint16_t max_response_packet_size;
/* Flags; see EC_PROTOCOL_INFO_* */
uint32_t flags;
} __packed;
/*****************************************************************************/
/* Real-time clock */
/* RTC params and response structures */
struct ec_params_rtc {
uint32_t time;
} __packed;
struct ec_response_rtc {
uint32_t time;
} __packed;
/* These use ec_response_rtc */
#define EC_CMD_RTC_GET_VALUE 0x44
#define EC_CMD_RTC_GET_ALARM 0x45
/* These all use ec_params_rtc */
#define EC_CMD_RTC_SET_VALUE 0x46
#define EC_CMD_RTC_SET_ALARM 0x47
/*****************************************************************************/
/* MKBP - Matrix KeyBoard Protocol */
/*
* Read key state
*
* Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for
* expected response size.
*/
#define EC_CMD_MKBP_STATE 0x60
/* Simulate key press */
#define EC_CMD_MKBP_SIMULATE_KEY 0x62
struct ec_params_mkbp_simulate_key {
uint8_t col;
uint8_t row;
uint8_t pressed;
} __packed;
/* Configure keyboard scanning */
#define EC_CMD_MKBP_SET_CONFIG 0x64
#define EC_CMD_MKBP_GET_CONFIG 0x65
/* flags */
enum mkbp_config_flags {
EC_MKBP_FLAGS_ENABLE = 1, /* Enable keyboard scanning */
};
enum mkbp_config_valid {
EC_MKBP_VALID_SCAN_PERIOD = 1 << 0,
EC_MKBP_VALID_POLL_TIMEOUT = 1 << 1,
EC_MKBP_VALID_MIN_POST_SCAN_DELAY = 1 << 3,
EC_MKBP_VALID_OUTPUT_SETTLE = 1 << 4,
EC_MKBP_VALID_DEBOUNCE_DOWN = 1 << 5,
EC_MKBP_VALID_DEBOUNCE_UP = 1 << 6,
EC_MKBP_VALID_FIFO_MAX_DEPTH = 1 << 7,
};
/* Configuration for our key scanning algorithm */
struct ec_mkbp_config {
uint32_t valid_mask; /* valid fields */
uint8_t flags; /* some flags (enum mkbp_config_flags) */
uint8_t valid_flags; /* which flags are valid */
uint16_t scan_period_us; /* period between start of scans */
/* revert to interrupt mode after no activity for this long */
uint32_t poll_timeout_us;
/*
* minimum post-scan relax time. Once we finish a scan we check
* the time until we are due to start the next one. If this time is
* shorter this field, we use this instead.
*/
uint16_t min_post_scan_delay_us;
/* delay between setting up output and waiting for it to settle */
uint16_t output_settle_us;
uint16_t debounce_down_us; /* time for debounce on key down */
uint16_t debounce_up_us; /* time for debounce on key up */
/* maximum depth to allow for fifo (0 = no keyscan output) */
uint8_t fifo_max_depth;
} __packed;
struct ec_params_mkbp_set_config {
struct ec_mkbp_config config;
} __packed;
struct ec_response_mkbp_get_config {
struct ec_mkbp_config config;
} __packed;
/* Run the key scan emulation */
#define EC_CMD_KEYSCAN_SEQ_CTRL 0x66
enum ec_keyscan_seq_cmd {
EC_KEYSCAN_SEQ_STATUS = 0, /* Get status information */
EC_KEYSCAN_SEQ_CLEAR = 1, /* Clear sequence */
EC_KEYSCAN_SEQ_ADD = 2, /* Add item to sequence */
EC_KEYSCAN_SEQ_START = 3, /* Start running sequence */
EC_KEYSCAN_SEQ_COLLECT = 4, /* Collect sequence summary data */
};
enum ec_collect_flags {
/*
* Indicates this scan was processed by the EC. Due to timing, some
* scans may be skipped.
*/
EC_KEYSCAN_SEQ_FLAG_DONE = 1 << 0,
};
struct ec_collect_item {
uint8_t flags; /* some flags (enum ec_collect_flags) */
};
struct ec_params_keyscan_seq_ctrl {
uint8_t cmd; /* Command to send (enum ec_keyscan_seq_cmd) */
union {
struct {
uint8_t active; /* still active */
uint8_t num_items; /* number of items */
/* Current item being presented */
uint8_t cur_item;
} status;
struct {
/*
* Absolute time for this scan, measured from the
* start of the sequence.
*/
uint32_t time_us;
uint8_t scan[0]; /* keyscan data */
} add;
struct {
uint8_t start_item; /* First item to return */
uint8_t num_items; /* Number of items to return */
} collect;
};
} __packed;
struct ec_result_keyscan_seq_ctrl {
union {
struct {
uint8_t num_items; /* Number of items */
/* Data for each item */
struct ec_collect_item item[0];
} collect;
};
} __packed;
/*
* Get the next pending MKBP event.
*
* Returns EC_RES_UNAVAILABLE if there is no event pending.
*/
#define EC_CMD_GET_NEXT_EVENT 0x67
enum ec_mkbp_event {
/* Keyboard matrix changed. The event data is the new matrix state. */
EC_MKBP_EVENT_KEY_MATRIX = 0,
/* New host event. The event data is 4 bytes of host event flags. */
EC_MKBP_EVENT_HOST_EVENT = 1,
/* New Sensor FIFO data. The event data is fifo_info structure. */
EC_MKBP_EVENT_SENSOR_FIFO = 2,
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
};
/*
* Resend last response (not supported on LPC).
*
* Returns EC_RES_UNAVAILABLE if there is no response available - for example,
* there was no previous command, or the previous command's response was too
* big to save.
*/
#define EC_CMD_RESEND_RESPONSE 0xdb
/*
* This header byte on a command indicate version 0. Any header byte less
* than this means that we are talking to an old EC which doesn't support
@@ -619,39 +302,6 @@ enum {
CROS_EC_SPI_OUT_HDR_SIZE = 3
};
static int send_packet(const void *dout, uint32_t dout_len,
void *din, uint32_t din_len)
{
while (grub_get_time_us() - last_transfer < 200)
;
if (spi_start())
return -1;
// Allow EC to ramp up clock after being awaken.
// See chrome-os-partner:32223 for more details.
grub_microsleep (100);
if (spi_send (dout, dout_len)) {
stop_bus();
return -1;
}
// Wait until the EC is ready.
if (wait_for_frame()) {
stop_bus();
return -1;
}
if (spi_read(din, din_len)) {
stop_bus();
return -1;
}
stop_bus();
return 0;
}
static grub_uint8_t busbuf[256];
#define MSG_BYTES sizeof (busbuf)
@@ -767,215 +417,6 @@ static int send_command(uint8_t cmd, int cmd_version,
/* Timeout waiting for a flash erase command to complete */
static const int CROS_EC_CMD_TIMEOUT_MS = 5000;
static void cros_ec_dump_data(const char *name, int cmd, const void *data, int len)
{
(void) name;
(void) cmd;
(void) data;
(void) len;
#ifdef DEBUG
const uint8_t *bytes = data;
int i;
printf("%s: ", name);
if (cmd != -1)
printf("cmd=%#x: ", cmd);
for (i = 0; i < len; i++)
printf("%02x ", bytes[i]);
printf("\n");
#endif
}
/**
* Create a request packet for protocol version 3.
*
* @param rq Request structure to fill
* @param rq_size Size of request structure, including data
* @param cmd Command to send (EC_CMD_...)
* @param cmd_version Version of command to send (EC_VER_...)
* @param dout Output data (may be NULL If dout_len=0)
* @param dout_len Size of output data in bytes
* @return packet size in bytes, or <0 if error.
*/
static int create_proto3_request(struct ec_host_request *rq, int rq_size,
int cmd, int cmd_version,
const void *dout, int dout_len)
{
int out_bytes = dout_len + sizeof(*rq);
/* Fail if output size is too big */
if (out_bytes > rq_size) {
printf("%s: Cannot send %d bytes\n", __func__, dout_len);
return -EC_RES_REQUEST_TRUNCATED;
}
/* Fill in request packet */
rq->struct_version = EC_HOST_REQUEST_VERSION;
rq->checksum = 0;
rq->command = cmd;
rq->command_version = cmd_version;
rq->reserved = 0;
rq->data_len = dout_len;
/* Copy data after header */
memcpy(rq + 1, dout, dout_len);
/* Write checksum field so the entire packet sums to 0 */
rq->checksum = (uint8_t)(-cros_ec_calc_checksum(rq, out_bytes));
cros_ec_dump_data("out", cmd, rq, out_bytes);
/* Return size of request packet */
return out_bytes;
}
/**
* Prepare the device to receive a protocol version 3 response.
*
* @param rs_size Maximum size of response in bytes
* @param din_len Maximum amount of data in the response
* @return maximum expected number of bytes in response, or <0 if error.
*/
static int prepare_proto3_response_buffer(int rs_size, int din_len)
{
int in_bytes = din_len + sizeof(struct ec_host_response);
/* Fail if input size is too big */
if (in_bytes > rs_size) {
printf("%s: Cannot receive %d bytes\n", __func__, din_len);
return -EC_RES_RESPONSE_TOO_BIG;
}
/* Return expected size of response packet */
return in_bytes;
}
/**
* Process a protocol version 3 response packet.
*
* @param resp Response structure to parse
* @param dinp Returns pointer to response data
* @param din_len Maximum size of data in response in bytes
* @return number of bytes of response data, or <0 if error
*/
static int handle_proto3_response(struct ec_host_response *rs,
uint8_t **dinp, int din_len)
{
int in_bytes;
int csum;
cros_ec_dump_data("in-header", -1, rs, sizeof(*rs));
/* Check input data */
if (rs->struct_version != EC_HOST_RESPONSE_VERSION) {
printf("%s: EC response version mismatch\n", __func__);
return -EC_RES_INVALID_RESPONSE;
}
if (rs->reserved) {
printf("%s: EC response reserved != 0\n", __func__);
return -EC_RES_INVALID_RESPONSE;
}
if (rs->data_len > din_len) {
printf("%s: EC returned too much data\n", __func__);
return -EC_RES_RESPONSE_TOO_BIG;
}
cros_ec_dump_data("in-data", -1, rs + sizeof(*rs), rs->data_len);
/* Update in_bytes to actual data size */
in_bytes = sizeof(*rs) + rs->data_len;
/* Verify checksum */
csum = cros_ec_calc_checksum(rs, in_bytes);
if (csum) {
printf("%s: EC response checksum invalid: 0x%02x\n", __func__,
csum);
return -EC_RES_INVALID_CHECKSUM;
}
/* Return error result, if any */
if (rs->result)
return -(int)rs->result;
/* If the caller wants the response data, copy it out */
if (dinp)
memcpy(dinp, rs + 1, din_len);
return rs->data_len;
}
static int send_command_proto3_work(int cmd, int cmd_version,
const void *dout, int dout_len,
void *dinp, int din_len)
{
int out_bytes, in_bytes;
int rv;
/* Create request packet */
out_bytes = create_proto3_request(proto3_request, proto3_request_size,
cmd, cmd_version, dout, dout_len);
if (out_bytes < 0)
return out_bytes;
/* Prepare response buffer */
in_bytes = prepare_proto3_response_buffer(proto3_response_size,
din_len);
if (in_bytes < 0)
return in_bytes;
rv = send_packet(proto3_request, out_bytes,
proto3_response, in_bytes);
if (rv < 0)
return rv;
/* Process the response */
return handle_proto3_response(proto3_response, dinp, din_len);
}
static int send_command_proto3(int cmd, int cmd_version,
const void *dout, int dout_len,
void *dinp, int din_len)
{
int rv;
rv = send_command_proto3_work(cmd, cmd_version, dout, dout_len,
dinp, din_len);
/* If the command doesn't complete, wait a while */
if (rv == -EC_RES_IN_PROGRESS) {
struct ec_response_get_comms_status resp;
uint64_t start;
/* Wait for command to complete */
start = grub_get_time_ms();
do {
int ret;
mdelay(50); /* Insert some reasonable delay */
ret = send_command_proto3_work(EC_CMD_GET_COMMS_STATUS,
0, NULL, 0, &resp, sizeof(resp));
if (ret < 0)
return ret;
if (grub_get_time_ms() - start > CROS_EC_CMD_TIMEOUT_MS) {
printf("%s: Command %#02x timeout",
__func__, cmd);
return -EC_RES_TIMEOUT;
}
} while (resp.flags & EC_COMMS_STATUS_PROCESSING);
/* OK it completed, so read the status response */
rv = send_command_proto3_work(EC_CMD_RESEND_RESPONSE,
0, NULL, 0, dinp, din_len);
}
return rv;
}
/**
* Send a command to the ChromeOS EC device and optionally return the reply.
*
@@ -1002,36 +443,6 @@ static int send_command_proto2(int cmd, int cmd_version,
len = send_command(cmd, cmd_version, dout,
dout_len, din, din_len);
/* If the command doesn't complete, wait a while */
if (len == -EC_RES_IN_PROGRESS) {
struct ec_response_get_comms_status resp;
uint64_t start;
/* Wait for command to complete */
start = grub_get_time_ms();
do {
int ret;
mdelay(50); /* Insert some reasonable delay */
ret = send_command(
EC_CMD_GET_COMMS_STATUS,
0, NULL, 0, &resp, sizeof(resp));
if (ret < 0)
return ret;
if (grub_get_time_ms() - start > CROS_EC_CMD_TIMEOUT_MS) {
printf("%s: Command %#02x timeout",
__func__, cmd);
return -EC_RES_TIMEOUT;
}
} while (resp.flags & EC_COMMS_STATUS_PROCESSING);
/* OK it completed, so read the status response */
len = send_command(
EC_CMD_RESEND_RESPONSE,
0, NULL, 0, din, din_len);
}
#ifdef DEBUG
printf("%s: len=%d, din=%p\n", __func__, len, din);
#endif
@@ -1043,20 +454,8 @@ static int ec_command(int cmd, int cmd_version,
const void *dout, int dout_len,
void *din, int din_len)
{
if (!initialized && cros_ec_init())
return -1;
return send_command_func(cmd, cmd_version, dout, dout_len,
din, din_len);
}
static int cros_ec_get_protocol_info(struct ec_response_get_protocol_info *info)
{
if (ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, info,
sizeof(*info)) < (int)sizeof(*info))
return -1;
return 0;
return send_command_proto2(cmd, cmd_version, dout, dout_len,
din, din_len);
}
int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan)
@@ -1067,69 +466,3 @@ int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan)
return 0;
}
static int set_max_proto3_sizes(int request_size, int response_size,
int passthru_size)
{
grub_free(proto3_request);
grub_free(proto3_response);
if (request_size)
proto3_request = grub_malloc(request_size);
else
proto3_request = NULL;
if (response_size)
proto3_response = grub_malloc(response_size);
else
proto3_response = NULL;
proto3_request_size = request_size;
proto3_response_size = response_size;
max_param_size = proto3_request_size - sizeof(struct ec_host_request);
passthru_param_size = passthru_size - sizeof(struct ec_host_request);
if (passthru_param_size > max_param_size)
passthru_param_size = max_param_size;
return 0;
}
int cros_ec_init(void)
{
if (initialized)
return 0;
initialized = 1;
// Figure out what protocol version to use.
send_command_func = &send_command_proto3;
if (set_max_proto3_sizes(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
DEFAULT_BUF_SIZE))
return -1;
struct ec_response_get_protocol_info info;
if (cros_ec_get_protocol_info(&info)) {
set_max_proto3_sizes(0, 0, 0);
send_command_func = NULL;
} else {
printf("%s: CrosEC protocol v3 supported (%d, %d)\n",
__func__,
info.max_request_packet_size,
info.max_response_packet_size);
set_max_proto3_sizes(info.max_request_packet_size,
info.max_response_packet_size,
0);
}
if (!send_command_func) {
// Fall back to protocol version 2.
send_command_func = &send_command_proto2;
max_param_size = EC_PROTO2_MAX_PARAM_SIZE;
}
return 0;
}
-2
View File
@@ -54,6 +54,4 @@ typedef struct CrosEcBusOps
void (*write)(const grub_uint8_t *data, grub_uint16_t port, int size);
} CrosEcBusOps;
int cros_ec_set_bus(CrosEcBusOps *bus);
int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan);
int cros_ec_init(void);