1 /*
2  * Copyright 2020 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_
9 
10 /**
11  * @file
12  *
13  * @brief Public APIs for the eSPI emulation drivers.
14  */
15 
16 #include <zephyr/types.h>
17 #include <device.h>
18 
19 /**
20  * @brief eSPI Emulation Interface
21  * @defgroup espi_emul_interface eSPI Emulation Interface
22  * @ingroup io_emulators
23  * @{
24  */
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #define EMUL_ESPI_HOST_CHIPSEL 0
31 
32 struct espi_emul;
33 
34 /**
35  * Passes eSPI virtual wires set request (virtual wire packet) to the emulator.
36  * The emulator updates the state (level) of its virtual wire.
37  *
38  * @param emul Emulator instance
39  * @param vw The signal to be set.
40  * @param level The level of signal requested LOW(0) or HIGH(1).
41  *
42  * @retval 0 If successful.
43  * @retval -EIO General input / output error.
44  */
45 typedef int (*emul_espi_api_set_vw)(struct espi_emul *emul,
46 				    enum espi_vwire_signal vw,
47 				    uint8_t level);
48 
49 /**
50  * Passes eSPI virtual wires get request (virtual wire packet) to the emulator.
51  * The emulator returns the state (level) of its virtual wire.
52  *
53  * @param emul Emulator instance
54  * @param vw The signal to be get.
55  * @param level The level of the signal to be get.
56  *
57  * @retval 0 If successful.
58  * @retval -EIO General input / output error.
59  */
60 typedef int (*emul_espi_api_get_vw)(struct espi_emul *emul,
61 				    enum espi_vwire_signal vw,
62 				    uint8_t *level);
63 
64 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
65 /**
66  * Get the ACPI shared memory address owned by the emulator.
67  *
68  * @param emul Emulator instance.
69  *
70  * @retval The address of the memory.
71  */
72 typedef uintptr_t (*emul_espi_api_get_acpi_shm)(struct espi_emul *emul);
73 #endif
74 
75 /**
76  * Find an emulator present on a eSPI bus
77  *
78  * At present the function is used only to find an emulator of the host
79  * device. It may be useful in systems with the SPI flash chips.
80  *
81  * @param dev eSPI emulation controller device
82  * @param chipsel Chip-select value
83  * @return emulator to use
84  * @return NULL if not found
85  */
86 typedef struct espi_emul *(*emul_find_emul)(const struct device *dev,
87 					    unsigned int chipsel);
88 
89 /**
90  * Triggers an event on the emulator of eSPI controller side which causes
91  * calling specific callbacks.
92  *
93  * @param dev Device instance of emulated eSPI controller
94  * @param evt Event to be triggered
95  *
96  * @retval 0 If successful.
97  * @retval -EIO General input / output error.
98  */
99 typedef int (*emul_trigger_event)(const struct device *dev,
100 				  struct espi_event *evt);
101 
102 /** Definition of the eSPI device emulator API */
103 struct emul_espi_device_api {
104 	emul_espi_api_set_vw set_vw;
105 	emul_espi_api_get_vw get_vw;
106 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
107 	emul_espi_api_get_acpi_shm get_acpi_shm;
108 #endif
109 };
110 
111 /** Node in a linked list of emulators for eSPI devices */
112 struct espi_emul {
113 	sys_snode_t node;
114 	/* API provided for this device */
115 	const struct emul_espi_device_api *api;
116 	/* eSPI chip-select of the emulated device */
117 	uint16_t chipsel;
118 };
119 
120 /** Definition of the eSPI controller emulator API */
121 struct emul_espi_driver_api {
122 	/* The struct espi_driver_api has to be first in
123 	 * struct emul_espi_driver_api to make pointer casting working
124 	 */
125 	struct espi_driver_api espi_api;
126 	/* The rest, emulator specific functions */
127 	emul_trigger_event trigger_event;
128 	emul_find_emul find_emul;
129 };
130 
131 /**
132  * Register an emulated device on the controller
133  *
134  * @param dev Device that will use the emulator
135  * @param name User-friendly name for this emulator
136  * @param emul eSPI emulator to use
137  * @return 0 indicating success (always)
138  */
139 int espi_emul_register(const struct device *dev, const char *name,
140 		       struct espi_emul *emul);
141 
142 /**
143  * Sets the eSPI virtual wire on the host side, which will
144  * trigger a proper event(and callbacks) on the emulated eSPI controller
145  *
146  * @param espi_dev eSPI emulation controller device
147  * @param vw The signal to be set.
148  * @param level The level of the signal to be set.
149  *
150  * @retval 0 If successful.
151  * @retval -EIO General input / output error.
152  */
153 int emul_espi_host_send_vw(const struct device *espi_dev,
154 			   enum espi_vwire_signal vw, uint8_t level);
155 
156 /**
157  * Perform port80 write on the emulated host side, which will
158  * trigger a proper event(and callbacks) on the emulated eSPI controller
159  *
160  * @param espi_dev eSPI emulation controller device
161  * @param data The date to be written.
162  *
163  * @retval 0 If successful.
164  * @retval -EIO General input / output error.
165  */
166 int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data);
167 
168 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
169 /**
170  * Get the host device's ACPI shared memory start address. The size of the region is
171  * CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE.
172  *
173  * @param espi_dev eSPI emulation controller device.
174  * @return Address of the start of the ACPI shared memory.
175  */
176 uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev);
177 #endif
178 
179 
180 #ifdef __cplusplus
181 }
182 #endif
183 
184 /**
185  * @}
186  */
187 
188 #endif /* ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_ */
189