Commit 425d2051 authored by Reka Norman's avatar Reka Norman Committed by Hans Verkuil

media: cros-ec-cec: Support receiving messages from multiple ports

Currently, received messages are sent from the EC in the cec_message
MKBP event. Since the size of ec_response_get_next_data_v1 is 16 bytes,
which is also the maximum size of a CEC message, there is no space to
add a port parameter. Increasing the size of
ec_response_get_next_data_v1 is an option, but this would increase
EC-kernel traffic for all MKBP event types.

Instead, use an event to notify that data is ready, and add a new read
command to read the data.

For backwards compatibility with old EC firmware, continue to handle
cec_message events as well.
Signed-off-by: default avatarReka Norman <rekanorman@chromium.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 1cabf526
......@@ -59,19 +59,63 @@ struct cros_ec_cec {
struct cros_ec_cec_port *ports[EC_CEC_MAX_PORTS];
};
static void cros_ec_cec_received_message(struct cros_ec_cec_port *port,
uint8_t *msg, uint8_t len)
{
if (len > CEC_MAX_MSG_SIZE)
len = CEC_MAX_MSG_SIZE;
port->rx_msg.len = len;
memcpy(port->rx_msg.msg, msg, len);
cec_received_msg(port->adap, &port->rx_msg);
}
static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
{
struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec;
uint8_t *cec_message = cros_ec->event_data.data.cec_message;
unsigned int len = cros_ec->event_size;
struct cros_ec_cec_port *port = cros_ec_cec->ports[CEC_PORT];
struct cros_ec_cec_port *port;
/*
* There are two ways of receiving CEC messages:
* 1. Old EC firmware which only supports one port sends the data in a
* cec_message MKBP event.
* 2. New EC firmware which supports multiple ports uses
* EC_MKBP_CEC_HAVE_DATA to notify that data is ready and
* EC_CMD_CEC_READ_MSG to read it.
* Check that the EC only has one CEC port, and then we can assume the
* message is from port 0.
*/
if (cros_ec_cec->num_ports != 1) {
dev_err(cros_ec->dev,
"received cec_message on device with %d ports\n",
cros_ec_cec->num_ports);
return;
}
port = cros_ec_cec->ports[0];
if (len > CEC_MAX_MSG_SIZE)
len = CEC_MAX_MSG_SIZE;
port->rx_msg.len = len;
memcpy(port->rx_msg.msg, cec_message, len);
cros_ec_cec_received_message(port, cec_message, len);
}
cec_received_msg(port->adap, &port->rx_msg);
static void cros_ec_cec_read_message(struct cros_ec_cec_port *port)
{
struct cros_ec_device *cros_ec = port->cros_ec_cec->cros_ec;
struct ec_params_cec_read params = {
.port = port->port_num,
};
struct ec_response_cec_read response;
int ret;
ret = cros_ec_cmd(cros_ec, 0, EC_CMD_CEC_READ_MSG, &params,
sizeof(params), &response, sizeof(response));
if (ret < 0) {
dev_err(cros_ec->dev,
"error reading CEC message on EC: %d\n", ret);
return;
}
cros_ec_cec_received_message(port, response.msg, response.msg_len);
}
static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
......@@ -97,6 +141,9 @@ static void handle_cec_event(struct cros_ec_cec *cros_ec_cec)
cec_transmit_attempt_done(port->adap,
CEC_TX_STATUS_MAX_RETRIES |
CEC_TX_STATUS_NACK);
if (events & EC_MKBP_CEC_HAVE_DATA)
cros_ec_cec_read_message(port);
}
static int cros_ec_cec_event(struct notifier_block *nb,
......
......@@ -4473,6 +4473,27 @@ struct ec_params_cec_write_v1 {
uint8_t msg[MAX_CEC_MSG_LEN];
} __ec_align1;
/* CEC message read from a CEC bus reported back to the AP */
#define EC_CMD_CEC_READ_MSG 0x00B9
/**
* struct ec_params_cec_read - Read a message from the CEC bus
* @port: CEC port to read a message on
*/
struct ec_params_cec_read {
uint8_t port;
} __ec_align1;
/**
* struct ec_response_cec_read - Message read from the CEC bus
* @msg_len: length of msg in bytes
* @msg: message content read from the CEC bus
*/
struct ec_response_cec_read {
uint8_t msg_len;
uint8_t msg[MAX_CEC_MSG_LEN];
} __ec_align1;
/* Set various CEC parameters */
#define EC_CMD_CEC_SET 0x00BA
......@@ -4529,6 +4550,8 @@ enum mkbp_cec_event {
EC_MKBP_CEC_SEND_OK = BIT(0),
/* Outgoing message was not acknowledged */
EC_MKBP_CEC_SEND_FAILED = BIT(1),
/* Incoming message can be read out by AP */
EC_MKBP_CEC_HAVE_DATA = BIT(2),
};
/*****************************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment