/* * Copyright 2020 Google LLC * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_ #define ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_ #include #include #include #include #include /** * @file * * @brief Public APIs for the eSPI emulation drivers. */ /** * @brief eSPI Emulation Interface * @defgroup espi_emul_interface eSPI Emulation Interface * @ingroup io_emulators * @{ */ #ifdef __cplusplus extern "C" { #endif #define EMUL_ESPI_HOST_CHIPSEL 0 struct espi_emul; /** * Passes eSPI virtual wires set request (virtual wire packet) to the emulator. * The emulator updates the state (level) of its virtual wire. * * @param target The device Emulator instance * @param vw The signal to be set. * @param level The level of signal requested LOW(0) or HIGH(1). * * @retval 0 If successful. * @retval -EIO General input / output error. */ typedef int (*emul_espi_api_set_vw)(const struct emul *target, enum espi_vwire_signal vw, uint8_t level); /** * Passes eSPI virtual wires get request (virtual wire packet) to the emulator. * The emulator returns the state (level) of its virtual wire. * * @param target The device Emulator instance * @param vw The signal to be get. * @param level The level of the signal to be get. * * @retval 0 If successful. * @retval -EIO General input / output error. */ typedef int (*emul_espi_api_get_vw)(const struct emul *target, enum espi_vwire_signal vw, uint8_t *level); #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION /** * Get the ACPI shared memory address owned by the emulator. * * @param target The device Emulator instance * * @retval The address of the memory. */ typedef uintptr_t (*emul_espi_api_get_acpi_shm)(const struct emul *target); #endif /** * Find an emulator present on a eSPI bus * * At present the function is used only to find an emulator of the host * device. It may be useful in systems with the SPI flash chips. * * @param dev eSPI emulation controller device * @param chipsel Chip-select value * @return espi_emul to use * @return NULL if not found */ typedef struct espi_emul *(*emul_find_emul)(const struct device *dev, unsigned int chipsel); /** * Triggers an event on the emulator of eSPI controller side which causes * calling specific callbacks. * * @param dev Device instance of emulated eSPI controller * @param evt Event to be triggered * * @retval 0 If successful. * @retval -EIO General input / output error. */ typedef int (*emul_trigger_event)(const struct device *dev, struct espi_event *evt); /** Definition of the eSPI device emulator API */ struct emul_espi_device_api { emul_espi_api_set_vw set_vw; emul_espi_api_get_vw get_vw; #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION emul_espi_api_get_acpi_shm get_acpi_shm; #endif }; /** Node in a linked list of emulators for eSPI devices */ struct espi_emul { sys_snode_t node; /** Target emulator - REQUIRED for all emulated bus nodes of any type */ const struct emul *target; /** API provided for this device */ const struct emul_espi_device_api *api; /** eSPI chip-select of the emulated device */ uint16_t chipsel; }; /** Definition of the eSPI controller emulator API */ struct emul_espi_driver_api { /* The struct espi_driver_api has to be first in * struct emul_espi_driver_api to make pointer casting working */ struct espi_driver_api espi_api; /* The rest, emulator specific functions */ emul_trigger_event trigger_event; emul_find_emul find_emul; }; /** * Register an emulated device on the controller * * @param dev Device that will use the emulator * @param emul eSPI emulator to use * @return 0 indicating success (always) */ int espi_emul_register(const struct device *dev, struct espi_emul *emul); /** * Sets the eSPI virtual wire on the host side, which will * trigger a proper event(and callbacks) on the emulated eSPI controller * * @param espi_dev eSPI emulation controller device * @param vw The signal to be set. * @param level The level of the signal to be set. * * @retval 0 If successful. * @retval -EIO General input / output error. */ int emul_espi_host_send_vw(const struct device *espi_dev, enum espi_vwire_signal vw, uint8_t level); /** * Perform port80 write on the emulated host side, which will * trigger a proper event(and callbacks) on the emulated eSPI controller * * @param espi_dev eSPI emulation controller device * @param data The date to be written. * * @retval 0 If successful. * @retval -EIO General input / output error. */ int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data); #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION /** * Get the host device's ACPI shared memory start address. The size of the region is * CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE. * * @param espi_dev eSPI emulation controller device. * @return Address of the start of the ACPI shared memory. */ uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev); #endif #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_ */