ec_host_cmd_periph: add device API
The host command peripheral device API abstracts how an embedded controller sends and receives data from a host on a bus. Each bus like eSPI, SPI, or I2C would implement their own host command peripheral device. Each hardware device would then handle the necessary hardware access to send and receive data over that bus. The chosen host command peripheral device will be used by the host command handler framework to send and receive host data correctly. Signed-off-by: Jett Rink <jettrink@google.com>
This commit is contained in:
parent
35ad4e8632
commit
703fe86220
11 changed files with 350 additions and 0 deletions
8
drivers/ec_host_cmd_periph/CMakeLists.txt
Normal file
8
drivers/ec_host_cmd_periph/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(
|
||||
CONFIG_EC_HOST_CMD_SIMULATOR
|
||||
ec_host_cmd_simulator.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE ec_host_cmd_periph_handlers.c)
|
20
drivers/ec_host_cmd_periph/Kconfig
Normal file
20
drivers/ec_host_cmd_periph/Kconfig
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Host Command Peripheral simulator config
|
||||
|
||||
# Copyright (c) 2020 Google LLC
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig EC_HOST_CMD_PERIPH
|
||||
bool "Embedded Controller Host Command peripheral support"
|
||||
help
|
||||
Enable the embedded controller host command peripheral driver. This
|
||||
is needed by the EC host command framework to send and receive data
|
||||
on the appropriate EC host bus.
|
||||
|
||||
if EC_HOST_CMD_PERIPH
|
||||
|
||||
config EC_HOST_CMD_SIMULATOR
|
||||
bool "Embedded Controller Host Command Peripheral Simulator"
|
||||
help
|
||||
Enable the EC host command simulator.
|
||||
|
||||
endif # EC_HOST_CMD_PERIPH
|
40
drivers/ec_host_cmd_periph/ec_host_cmd_periph_handlers.c
Normal file
40
drivers/ec_host_cmd_periph/ec_host_cmd_periph_handlers.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Google LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/ec_host_cmd_periph.h>
|
||||
#include <syscall_handler.h>
|
||||
|
||||
static inline void
|
||||
z_vrfy_ec_host_cmd_periph_init(const struct device *dev,
|
||||
struct ec_host_cmd_periph_rx_ctx *rx_ctx)
|
||||
{
|
||||
struct ec_host_cmd_periph_rx_ctx local_rx_ctx;
|
||||
|
||||
Z_OOPS(Z_SYSCALL_OBJ_INIT(dev, K_OBJ_DRIVER_EC_HOST_CMD_PERIPH_API));
|
||||
|
||||
z_impl_host_cmd_periph_init(dev, &local_rx_ctx);
|
||||
|
||||
Z_OOPS(z_user_to_copy(&local_rx_ctx, rx_ctx, sizeof(*rx_ctx)));
|
||||
}
|
||||
#include <syscalls/ec_host_cmd_periph_init_mrsh.c>
|
||||
|
||||
static inline void
|
||||
z_vrfy_ec_host_cmd_periph_send(const struct device *dev,
|
||||
const struct ec_host_cmd_periph_tx_buf *tx_buf)
|
||||
{
|
||||
struct ec_host_cmd_periph_tx_buf local_tx_buf;
|
||||
|
||||
Z_OOPS(Z_SYSCALL_OBJ(dev, K_OBJ_DRIVER_EC_HOST_CMD_PERIPH_API));
|
||||
Z_OOPS(z_user_from_copy(&local_tx_buf, tx_buf, sizeof(*tx_buf)));
|
||||
|
||||
/* Ensure that user thread has acces to read buffer since
|
||||
* device will read from this memory location.
|
||||
*/
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_READ(local_tx_buf.buf, local_tx_buf.size));
|
||||
|
||||
z_impl_host_cmd_periph_send(dev, &local_tx_buf);
|
||||
}
|
||||
#include <syscalls/ec_host_cmd_periph_init_mrsh.c>
|
85
drivers/ec_host_cmd_periph/ec_host_cmd_simulator.c
Normal file
85
drivers/ec_host_cmd_periph/ec_host_cmd_simulator.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Google LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT zephyr_sim_ec_host_cmd_periph
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/ec_host_cmd_periph.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef CONFIG_ARCH_POSIX
|
||||
#error Simulator only valid on posix
|
||||
#endif
|
||||
|
||||
static uint8_t rx_buffer[256];
|
||||
static size_t rx_buffer_len;
|
||||
|
||||
/* Allow writing to rx buff at startup and block on reading. */
|
||||
static K_SEM_DEFINE(handler_owns, 0, 1);
|
||||
static K_SEM_DEFINE(dev_owns, 1, 1);
|
||||
|
||||
static ec_host_cmd_periph_api_send tx;
|
||||
|
||||
int ec_host_cmd_periph_sim_init(const struct device *dev,
|
||||
struct ec_host_cmd_periph_rx_ctx *rx_ctx)
|
||||
{
|
||||
if (rx_ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rx_ctx->buf = rx_buffer;
|
||||
rx_ctx->len = &rx_buffer_len;
|
||||
rx_ctx->dev_owns = &dev_owns;
|
||||
rx_ctx->handler_owns = &handler_owns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ec_host_cmd_periph_sim_send(const struct device *dev,
|
||||
const struct ec_host_cmd_periph_tx_buf *buf)
|
||||
{
|
||||
if (tx != NULL) {
|
||||
return tx(dev, buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ec_host_cmd_periph_sim_install_send_cb(ec_host_cmd_periph_api_send cb)
|
||||
{
|
||||
tx = cb;
|
||||
}
|
||||
|
||||
int ec_host_cmd_periph_sim_data_received(const uint8_t *buffer, size_t len)
|
||||
{
|
||||
if (sizeof(rx_buffer) < len) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (k_sem_take(&dev_owns, K_NO_WAIT) != 0) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
memcpy(rx_buffer, buffer, len);
|
||||
rx_buffer_len = len;
|
||||
|
||||
k_sem_give(&handler_owns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ec_host_cmd_periph_api ec_host_cmd_api = {
|
||||
.init = &ec_host_cmd_periph_sim_init,
|
||||
.send = &ec_host_cmd_periph_sim_send,
|
||||
};
|
||||
|
||||
static int ec_host_cmd_sim_init(const struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assume only one simulator */
|
||||
DEVICE_AND_API_INIT(ec_host_cmd_simulator, DT_INST_LABEL(0),
|
||||
ec_host_cmd_sim_init, NULL, NULL, POST_KERNEL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &ec_host_cmd_api);
|
Loading…
Add table
Add a link
Reference in a new issue