emul: Add support for non-bus emulators

Adds a stub API for a non bus emulators. The stub is used to keep the
rest of the emulation consistent.

Signed-off-by: Yuval Peress <peress@google.com>
This commit is contained in:
Yuval Peress 2024-01-04 02:08:59 -07:00 committed by Carles Cufí
parent 56de0a347e
commit a9afc5a7b8
2 changed files with 18 additions and 6 deletions

View file

@ -36,6 +36,7 @@ enum emul_bus_type {
EMUL_BUS_TYPE_I2C,
EMUL_BUS_TYPE_ESPI,
EMUL_BUS_TYPE_SPI,
EMUL_BUS_TYPE_NONE,
};
/**
@ -62,6 +63,14 @@ struct emul_list_for_bus {
*/
typedef int (*emul_init_t)(const struct emul *emul, const struct device *parent);
/**
* Emulator API stub when an emulator is not actually placed on a bus.
*/
struct no_bus_emul {
void *api;
uint16_t addr;
};
/** An emulator instance - represents the *target* emulated device/peripheral that is
* interacted with through an emulated bus. Instances of emulated bus nodes (e.g. i2c_emul)
* and emulators (i.e. struct emul) are exactly 1..1
@ -82,6 +91,7 @@ struct emul {
struct i2c_emul *i2c;
struct espi_emul *espi;
struct spi_emul *spi;
struct no_bus_emul *none;
} bus;
/** Address of the API structure exposed by the emulator instance */
const void *backend_api;
@ -101,10 +111,10 @@ struct emul {
#define Z_EMUL_REG_BUS_IDENTIFIER(_dev_node_id) (_CONCAT(_CONCAT(__emulreg_, _dev_node_id), _bus))
/* Conditionally places text based on what bus _dev_node_id is on. */
#define Z_EMUL_BUS(_dev_node_id, _i2c, _espi, _spi) \
#define Z_EMUL_BUS(_dev_node_id, _i2c, _espi, _spi, _none) \
COND_CODE_1(DT_ON_BUS(_dev_node_id, i2c), (_i2c), \
(COND_CODE_1(DT_ON_BUS(_dev_node_id, espi), (_espi), \
(COND_CODE_1(DT_ON_BUS(_dev_node_id, spi), (_spi), (-EINVAL))))))
(COND_CODE_1(DT_ON_BUS(_dev_node_id, spi), (_spi), (_none))))))
/**
* @brief Define a new emulator
*
@ -120,10 +130,10 @@ struct emul {
* @param _backend_api emulator-specific backend api
*/
#define EMUL_DT_DEFINE(node_id, init_fn, data_ptr, cfg_ptr, bus_api, _backend_api) \
static struct Z_EMUL_BUS(node_id, i2c_emul, espi_emul, spi_emul) \
static struct Z_EMUL_BUS(node_id, i2c_emul, espi_emul, spi_emul, no_bus_emul) \
Z_EMUL_REG_BUS_IDENTIFIER(node_id) = { \
.api = bus_api, \
.Z_EMUL_BUS(node_id, addr, chipsel, chipsel) = DT_REG_ADDR(node_id), \
.Z_EMUL_BUS(node_id, addr, chipsel, chipsel, addr) = DT_REG_ADDR(node_id), \
}; \
const STRUCT_SECTION_ITERABLE(emul, EMUL_DT_NAME_GET(node_id)) \
__used = { \
@ -132,8 +142,8 @@ struct emul {
.cfg = (cfg_ptr), \
.data = (data_ptr), \
.bus_type = Z_EMUL_BUS(node_id, EMUL_BUS_TYPE_I2C, EMUL_BUS_TYPE_ESPI, \
EMUL_BUS_TYPE_SPI), \
.bus = {.Z_EMUL_BUS(node_id, i2c, espi, spi) = \
EMUL_BUS_TYPE_SPI, EMUL_BUS_TYPE_NONE), \
.bus = {.Z_EMUL_BUS(node_id, i2c, espi, spi, none) = \
&(Z_EMUL_REG_BUS_IDENTIFIER(node_id))}, \
.backend_api = (_backend_api), \
};

View file

@ -55,6 +55,8 @@ int emul_init_for_bus(const struct device *dev)
case EMUL_BUS_TYPE_SPI:
emul->bus.spi->target = emul;
break;
case EMUL_BUS_TYPE_NONE:
break;
}
int rc = emul->init(emul, dev);