mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
Provide the required plumbing for the stm32 keyboard scan code so that the message layer will pick up keyboard scans. The design is as follows: - When a change in keyboard state is detected, the keyboard matrix scanning code will call the board-specific board_keyboard_scan_ready() function to interrupt the AP. - The AP will initiate a CMDC_KEY_STATE transaction over SPI or I2C - The SPI or I2C driver will call message_process_cmd() to process the command - This in turn will call keyboard_get_scan() to get the latest scan data For SPI: - The AP will initiate an 20-byte (or longer) SPI transaction - The EC will see the command, and provide the keyboard state in response, with the response being part of the same transaction For I2C: - The AP will initiate a 1-byte write to set the EC mode. - The AP will then initiate an 18-byte read, and the EC will send the message including keyboard state BUG=chromium-os:28925 TEST=build on daisy and discovery; run on daisy Change-Id: I905ef9d567e43d85fb851052f67586eff58e1167 Signed-off-by: Simon Glass <sjg@chromium.org>
94 lines
2.2 KiB
C
94 lines
2.2 KiB
C
/*
|
|
* This handles incoming commands and provides responses.
|
|
*
|
|
* Copyright (c) 2012 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.
|
|
*
|
|
* EC <--> AP message handling.
|
|
*/
|
|
|
|
#include "board.h"
|
|
#include "message.h"
|
|
#include "keyboard_scan.h"
|
|
#include "util.h"
|
|
|
|
/* Our ID message - Matrix KeyBoard Protocol */
|
|
static const char proto_id[] = "Google Chrome MKBP v1";
|
|
|
|
|
|
/**
|
|
* Get the response to a given command
|
|
*
|
|
* @param cmd Command byte to respond to
|
|
* @param buffp Buffer to use for data, or it can be updated to
|
|
* point to a new buffer
|
|
* @param max_len Number of bytes free at *buffp for the response.
|
|
* If the supplied buffer is used, this size must not
|
|
* be exceeded.
|
|
* @return number of bytes in response (which is in *buffp), or -1 on error
|
|
*/
|
|
static int message_get_response(int cmd, uint8_t **buffp, int max_len)
|
|
{
|
|
/*
|
|
* Invalid commands are ignored, just returning a stream of 0xff
|
|
* bytes.
|
|
*/
|
|
switch (cmd & MSG_CMD_MASK) {
|
|
case CMDC_NOP:
|
|
return 0;
|
|
case CMDC_ID:
|
|
*buffp = (char *)proto_id;
|
|
return sizeof(proto_id) - 1;
|
|
case CMDC_KEY_STATE:
|
|
return keyboard_get_scan(buffp, max_len);
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int message_process_cmd(int cmd, uint8_t *out_msg, int max_len)
|
|
{
|
|
uint8_t *msg;
|
|
int msg_len;
|
|
int need_copy;
|
|
int sum = 0;
|
|
int len;
|
|
int i;
|
|
|
|
msg = out_msg + MSG_HEADER_BYTES;
|
|
msg_len = message_get_response(cmd, &msg, max_len - MSG_PROTO_BYTES);
|
|
if (msg_len < 0)
|
|
return msg_len;
|
|
|
|
/*
|
|
* We add MSG_PROTO_BYTES bytes of overhead: truncate the reply
|
|
* if needed.
|
|
*/
|
|
if (msg_len + MSG_PROTO_BYTES > max_len)
|
|
msg_len = max_len - MSG_PROTO_BYTES;
|
|
len = msg_len + 4;
|
|
ASSERT(msg_len >= 0 && msg_len < 0xffff);
|
|
need_copy = msg != out_msg + MSG_HEADER_BYTES;
|
|
ASSERT(!need_copy ||
|
|
msg + msg_len < out_msg ||
|
|
msg > out_msg + sizeof(out_msg));
|
|
|
|
out_msg[0] = MSG_HEADER;
|
|
out_msg[1] = len & 0xff;
|
|
out_msg[2] = (len >> 8) & 0xff;
|
|
sum += MSG_HEADER + len + (len >> 8);
|
|
|
|
for (i = 0; i < msg_len; i++) {
|
|
if (need_copy)
|
|
out_msg[i + 3] = *msg;
|
|
sum += *msg;
|
|
}
|
|
out_msg[i + 3] = sum & 0xff;
|
|
out_msg[i + 4] = MSG_PREAMBLE;
|
|
|
|
return msg_len + MSG_PROTO_BYTES;
|
|
}
|