1 /*
2 * Copyright (c) 2019 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public APIs for eSPI driver
10 */
11
12 #ifndef ZEPHYR_INCLUDE_ESPI_H_
13 #define ZEPHYR_INCLUDE_ESPI_H_
14
15 #include <sys/__assert.h>
16 #include <zephyr/types.h>
17 #include <device.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24 * @brief eSPI Driver APIs
25 * @defgroup espi_interface ESPI Driver APIs
26 * @ingroup io_interfaces
27 * @{
28 */
29
30 /**
31 * @brief eSPI I/O mode capabilities
32 */
33 enum espi_io_mode {
34 ESPI_IO_MODE_SINGLE_LINE = BIT(0),
35 ESPI_IO_MODE_DUAL_LINES = BIT(1),
36 ESPI_IO_MODE_QUAD_LINES = BIT(2),
37 };
38
39 /**
40 *+----------------------------------------------------------------------+
41 *| |
42 *| eSPI host +-------------+ |
43 *| +-----------+ | Power | +----------+ |
44 *| |Out of band| | management | | GPIO | |
45 *| +------------+ |processor | | controller | | sources | |
46 *| | SPI flash | +-----------+ +-------------+ +----------+ |
47 *| | controller | | | | |
48 *| +------------+ | | | |
49 *| | | | +--------+ +---------------+ |
50 *| | | | | | |
51 *| | | +-----+ +--------+ +----------+ +----v-----+ |
52 *| | | | | LPC | | Tunneled | | Tunneled | |
53 *| | | | | bridge | | SMBus | | GPIO | |
54 *| | | | +--------+ +----------+ +----------+ |
55 *| | | | | | | |
56 *| | | | ------+ | | |
57 *| | | | | | | |
58 *| | | +------v-----+ +---v-------v-------------v----+ |
59 *| | | | eSPI Flash | | eSPI protocol block | |
60 *| | | | access +--->+ | |
61 *| | | +------------+ +------------------------------+ |
62 *| | | | |
63 *| | +-----------+ | |
64 *| | v v |
65 *| | XXXXXXXXXXXXXXXXXXXXXXX |
66 *| | XXXXXXXXXXXXXXXXXXXXX |
67 *| | XXXXXXXXXXXXXXXXXXX |
68 *+----------------------------------------------------------------------+
69 * | |
70 * v +-----------------+
71 * +---------+ | | | | | |
72 * | Flash | | | | | | |
73 * +---------+ | + + + + | eSPI bus
74 * | CH0 CH1 CH2 CH3 | (logical channels)
75 * | + + + + |
76 * | | | | | |
77 * +-----------------+
78 * |
79 *+-----------------------------------------------------------------------+
80 *| eSPI slave |
81 *| |
82 *| CH0 | CH1 | CH2 | CH3 |
83 *| eSPI endpoint | VWIRE | OOB | Flash |
84 *+-----------------------------------------------------------------------+
85 *
86 */
87
88 /**
89 * @brief eSPI channel.
90 *
91 * Identifies each eSPI logical channel supported by eSPI controller
92 * Each channel allows independent traffic, but the assignment of channel
93 * type to channel number is fixed.
94 *
95 * Note that generic commands are not associated with any channel, so traffic
96 * over eSPI can occur if all channels are disabled or not ready
97 */
98 enum espi_channel {
99 ESPI_CHANNEL_PERIPHERAL = BIT(0),
100 ESPI_CHANNEL_VWIRE = BIT(1),
101 ESPI_CHANNEL_OOB = BIT(2),
102 ESPI_CHANNEL_FLASH = BIT(3),
103 };
104
105 /**
106 * @brief eSPI bus event.
107 *
108 * eSPI bus event to indicate events for which user can register callbacks
109 */
110 enum espi_bus_event {
111 ESPI_BUS_RESET = BIT(0),
112 ESPI_BUS_EVENT_CHANNEL_READY = BIT(1),
113 ESPI_BUS_EVENT_VWIRE_RECEIVED = BIT(2),
114 ESPI_BUS_EVENT_OOB_RECEIVED = BIT(3),
115 ESPI_BUS_PERIPHERAL_NOTIFICATION = BIT(4),
116 };
117
118 /**
119 * @cond INTERNAL_HIDDEN
120 *
121 */
122 #define ESPI_PERIPHERAL_INDEX_0 0ul
123 #define ESPI_PERIPHERAL_INDEX_1 1ul
124 #define ESPI_PERIPHERAL_INDEX_2 2ul
125
126 #define ESPI_SLAVE_TO_MASTER 0ul
127 #define ESPI_MASTER_TO_SLAVE 1ul
128
129 #define ESPI_VWIRE_SRC_ID0 0ul
130 #define ESPI_VWIRE_SRC_ID1 1ul
131 #define ESPI_VWIRE_SRC_ID2 2ul
132 #define ESPI_VWIRE_SRC_ID3 3ul
133 #define ESPI_VWIRE_SRC_ID_MAX 4ul
134
135 #define ESPI_PERIPHERAL_NODATA 0ul
136
137 #define E8042_START_OPCODE 0x50
138 #define E8042_MAX_OPCODE 0x5F
139
140 #define EACPI_START_OPCODE 0x60
141 #define EACPI_MAX_OPCODE 0x6F
142
143 #define ECUSTOM_START_OPCODE 0xF0
144 #define ECUSTOM_MAX_OPCODE 0xFF
145
146 /** @endcond */
147
148 /**
149 * @brief eSPI peripheral notification type.
150 *
151 * eSPI peripheral notification event details to indicate which peripheral
152 * trigger the eSPI callback
153 */
154 enum espi_virtual_peripheral {
155 ESPI_PERIPHERAL_UART,
156 ESPI_PERIPHERAL_8042_KBC,
157 ESPI_PERIPHERAL_HOST_IO,
158 ESPI_PERIPHERAL_DEBUG_PORT80,
159 ESPI_PERIPHERAL_HOST_IO_PVT,
160 #if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD)
161 ESPI_PERIPHERAL_EC_HOST_CMD,
162 #endif /* CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD */
163 };
164
165 /**
166 * @brief eSPI cycle types supported over eSPI peripheral channel
167 */
168 enum espi_cycle_type {
169 ESPI_CYCLE_MEMORY_READ32,
170 ESPI_CYCLE_MEMORY_READ64,
171 ESPI_CYCLE_MEMORY_WRITE32,
172 ESPI_CYCLE_MEMORY_WRITE64,
173 ESPI_CYCLE_MESSAGE_NODATA,
174 ESPI_CYCLE_MESSAGE_DATA,
175 ESPI_CYCLE_OK_COMPLETION_NODATA,
176 ESPI_CYCLE_OKCOMPLETION_DATA,
177 ESPI_CYCLE_NOK_COMPLETION_NODATA,
178 };
179
180 /**
181 * @brief eSPI system platform signals that can be send or receive through
182 * virtual wire channel
183 */
184 enum espi_vwire_signal {
185 /* Virtual wires that can only be send from master to slave */
186 ESPI_VWIRE_SIGNAL_SLP_S3,
187 ESPI_VWIRE_SIGNAL_SLP_S4,
188 ESPI_VWIRE_SIGNAL_SLP_S5,
189 ESPI_VWIRE_SIGNAL_OOB_RST_WARN,
190 ESPI_VWIRE_SIGNAL_PLTRST,
191 ESPI_VWIRE_SIGNAL_SUS_STAT,
192 ESPI_VWIRE_SIGNAL_NMIOUT,
193 ESPI_VWIRE_SIGNAL_SMIOUT,
194 ESPI_VWIRE_SIGNAL_HOST_RST_WARN,
195 ESPI_VWIRE_SIGNAL_SLP_A,
196 ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK,
197 ESPI_VWIRE_SIGNAL_SUS_WARN,
198 ESPI_VWIRE_SIGNAL_SLP_WLAN,
199 ESPI_VWIRE_SIGNAL_SLP_LAN,
200 ESPI_VWIRE_SIGNAL_HOST_C10,
201 ESPI_VWIRE_SIGNAL_DNX_WARN,
202 /* Virtual wires that can only be send from slave to master */
203 ESPI_VWIRE_SIGNAL_PME,
204 ESPI_VWIRE_SIGNAL_WAKE,
205 ESPI_VWIRE_SIGNAL_OOB_RST_ACK,
206 ESPI_VWIRE_SIGNAL_SLV_BOOT_STS,
207 ESPI_VWIRE_SIGNAL_ERR_NON_FATAL,
208 ESPI_VWIRE_SIGNAL_ERR_FATAL,
209 ESPI_VWIRE_SIGNAL_SLV_BOOT_DONE,
210 ESPI_VWIRE_SIGNAL_HOST_RST_ACK,
211 ESPI_VWIRE_SIGNAL_RST_CPU_INIT,
212 /* System management interrupt */
213 ESPI_VWIRE_SIGNAL_SMI,
214 /* System control interrupt */
215 ESPI_VWIRE_SIGNAL_SCI,
216 ESPI_VWIRE_SIGNAL_DNX_ACK,
217 ESPI_VWIRE_SIGNAL_SUS_ACK,
218 };
219
220 /* eSPI LPC peripherals. */
221 enum lpc_peripheral_opcode {
222 /* Read transactions */
223 E8042_OBF_HAS_CHAR = 0x50,
224 E8042_IBF_HAS_CHAR,
225 /* Write transactions */
226 E8042_WRITE_KB_CHAR,
227 E8042_WRITE_MB_CHAR,
228 /* Write transactions without input parameters */
229 E8042_RESUME_IRQ,
230 E8042_PAUSE_IRQ,
231 E8042_CLEAR_OBF,
232 /* Status transactions */
233 E8042_READ_KB_STS,
234 E8042_SET_FLAG,
235 E8042_CLEAR_FLAG,
236 /* ACPI read transactions */
237 EACPI_OBF_HAS_CHAR = EACPI_START_OPCODE,
238 EACPI_IBF_HAS_CHAR,
239 /* ACPI write transactions */
240 EACPI_WRITE_CHAR,
241 /* ACPI status transactions */
242 EACPI_READ_STS,
243 EACPI_WRITE_STS,
244 #if defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
245 /* Shared memory region support to return the ACPI response data */
246 EACPI_GET_SHARED_MEMORY,
247 #endif /* CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION */
248 #if defined(CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE)
249 /* Other customized transactions */
250 ECUSTOM_HOST_SUBS_INTERRUPT_EN = ECUSTOM_START_OPCODE,
251 ECUSTOM_HOST_CMD_GET_PARAM_MEMORY,
252 ECUSTOM_HOST_CMD_SEND_RESULT,
253 #endif /* CONFIG_ESPI_PERIPHERAL_CUSTOM_OPCODE */
254 };
255
256 /* KBC 8042 event: Input Buffer Full */
257 #define HOST_KBC_EVT_IBF BIT(0)
258 /* KBC 8042 event: Output Buffer Empty */
259 #define HOST_KBC_EVT_OBE BIT(1)
260 /**
261 * @brief Bit field definition of evt_data in struct espi_event for KBC.
262 */
263 struct espi_evt_data_kbc {
264 uint32_t type:8;
265 uint32_t data:8;
266 uint32_t evt:8;
267 uint32_t reserved:8;
268 };
269
270 /**
271 * @brief Bit field definition of evt_data in struct espi_event for ACPI.
272 */
273 struct espi_evt_data_acpi {
274 uint32_t type:8;
275 uint32_t data:8;
276 uint32_t reserved:16;
277 };
278
279 /**
280 * @brief eSPI event
281 */
282 struct espi_event {
283 /** Event type */
284 enum espi_bus_event evt_type;
285 /** Additional details for bus event type */
286 uint32_t evt_details;
287 /** Data associated to the event */
288 uint32_t evt_data;
289 };
290
291 /**
292 * @brief eSPI bus configuration parameters
293 */
294 struct espi_cfg {
295 /** Supported I/O mode */
296 enum espi_io_mode io_caps;
297 /** Supported channels */
298 enum espi_channel channel_caps;
299 /** Maximum supported frequency in MHz */
300 uint8_t max_freq;
301 };
302
303 /**
304 * @brief eSPI peripheral request packet format
305 */
306 struct espi_request_packet {
307 enum espi_cycle_type cycle_type;
308 uint8_t tag;
309 uint16_t len;
310 uint32_t address;
311 uint8_t *data;
312 };
313
314 /**
315 * @brief eSPI out-of-band transaction packet format
316 */
317 struct espi_oob_packet {
318 uint8_t *buf;
319 uint16_t len;
320 };
321
322 /**
323 * @brief eSPI flash transactions packet format
324 */
325 struct espi_flash_packet {
326 uint8_t *buf;
327 uint32_t flash_addr;
328 uint16_t len;
329 };
330
331 struct espi_callback;
332
333 /**
334 * @typedef espi_callback_handler_t
335 * @brief Define the application callback handler function signature.
336 *
337 * @param dev Device struct for the eSPI device.
338 * @param cb Original struct espi_callback owning this handler.
339 * @param espi_evt event details that trigger the callback handler.
340 *
341 */
342 typedef void (*espi_callback_handler_t) (const struct device *dev,
343 struct espi_callback *cb,
344 struct espi_event espi_evt);
345
346 /**
347 * @cond INTERNAL_HIDDEN
348 *
349 * Used to register a callback in the driver instance callback list.
350 * As many callbacks as needed can be added as long as each of them
351 * are unique pointers of struct espi_callback.
352 * Beware such structure should not be allocated on stack.
353 *
354 * Note: To help setting it, see espi_init_callback() below
355 */
356 struct espi_callback {
357 /** This is meant to be used in the driver only */
358 sys_snode_t node;
359
360 /** Actual callback function being called when relevant */
361 espi_callback_handler_t handler;
362
363 /** An event which user is interested in, if 0 the callback
364 * will never be called. Such evt_mask can be modified whenever
365 * necessary by the owner, and thus will affect the handler being
366 * called or not.
367 */
368 enum espi_bus_event evt_type;
369 };
370 /** @endcond */
371
372 /**
373 * @cond INTERNAL_HIDDEN
374 *
375 * eSPI driver API definition and system call entry points
376 *
377 * (Internal use only.)
378 */
379 typedef int (*espi_api_config)(const struct device *dev, struct espi_cfg *cfg);
380 typedef bool (*espi_api_get_channel_status)(const struct device *dev,
381 enum espi_channel ch);
382 /* Logical Channel 0 APIs */
383 typedef int (*espi_api_read_request)(const struct device *dev,
384 struct espi_request_packet *req);
385 typedef int (*espi_api_write_request)(const struct device *dev,
386 struct espi_request_packet *req);
387 typedef int (*espi_api_lpc_read_request)(const struct device *dev,
388 enum lpc_peripheral_opcode op,
389 uint32_t *data);
390 typedef int (*espi_api_lpc_write_request)(const struct device *dev,
391 enum lpc_peripheral_opcode op,
392 uint32_t *data);
393 /* Logical Channel 1 APIs */
394 typedef int (*espi_api_send_vwire)(const struct device *dev,
395 enum espi_vwire_signal vw,
396 uint8_t level);
397 typedef int (*espi_api_receive_vwire)(const struct device *dev,
398 enum espi_vwire_signal vw,
399 uint8_t *level);
400 /* Logical Channel 2 APIs */
401 typedef int (*espi_api_send_oob)(const struct device *dev,
402 struct espi_oob_packet *pckt);
403 typedef int (*espi_api_receive_oob)(const struct device *dev,
404 struct espi_oob_packet *pckt);
405 /* Logical Channel 3 APIs */
406 typedef int (*espi_api_flash_read)(const struct device *dev,
407 struct espi_flash_packet *pckt);
408 typedef int (*espi_api_flash_write)(const struct device *dev,
409 struct espi_flash_packet *pckt);
410 typedef int (*espi_api_flash_erase)(const struct device *dev,
411 struct espi_flash_packet *pckt);
412 /* Callbacks and traffic intercept */
413 typedef int (*espi_api_manage_callback)(const struct device *dev,
414 struct espi_callback *callback,
415 bool set);
416
417 __subsystem struct espi_driver_api {
418 espi_api_config config;
419 espi_api_get_channel_status get_channel_status;
420 espi_api_read_request read_request;
421 espi_api_write_request write_request;
422 espi_api_lpc_read_request read_lpc_request;
423 espi_api_lpc_write_request write_lpc_request;
424 espi_api_send_vwire send_vwire;
425 espi_api_receive_vwire receive_vwire;
426 espi_api_send_oob send_oob;
427 espi_api_receive_oob receive_oob;
428 espi_api_flash_read flash_read;
429 espi_api_flash_write flash_write;
430 espi_api_flash_erase flash_erase;
431 espi_api_manage_callback manage_callback;
432 };
433
434 /**
435 * @endcond
436 */
437
438 /**
439 * @brief Configure operation of a eSPI controller.
440 *
441 * This routine provides a generic interface to override eSPI controller
442 * capabilities.
443 *
444 * If this eSPI controller is acting as slave, the values set here
445 * will be discovered as part through the GET_CONFIGURATION command
446 * issued by the eSPI master during initialization.
447 *
448 * If this eSPI controller is acting as master, the values set here
449 * will be used by eSPI master to determine minimum common capabilities with
450 * eSPI slave then send via SET_CONFIGURATION command.
451 *
452 * +--------+ +---------+ +------+ +---------+ +---------+
453 * | eSPI | | eSPI | | eSPI | | eSPI | | eSPI |
454 * | slave | | driver | | bus | | driver | | host |
455 * +--------+ +---------+ +------+ +---------+ +---------+
456 * | | | | |
457 * | espi_config | Set eSPI | Set eSPI | espi_config |
458 * +--------------+ ctrl regs | cap ctrl reg| +-----------+
459 * | +-------+ | +--------+ |
460 * | |<------+ | +------->| |
461 * | | | | |
462 * | | | | |
463 * | | | GET_CONFIGURATION | |
464 * | | +<------------------+ |
465 * | |<-----------| | |
466 * | | eSPI caps | | |
467 * | |----------->+ response | |
468 * | | |------------------>+ |
469 * | | | | |
470 * | | | SET_CONFIGURATION | |
471 * | | +<------------------+ |
472 * | | | accept | |
473 * | | +------------------>+ |
474 * + + + + +
475 *
476 * @param dev Pointer to the device structure for the driver instance.
477 * @param cfg the device runtime configuration for the eSPI controller.
478 *
479 * @retval 0 If successful.
480 * @retval -EIO General input / output error, failed to configure device.
481 * @retval -EINVAL invalid capabilities, failed to configure device.
482 * @retval -ENOTSUP capability not supported by eSPI slave.
483 */
484 __syscall int espi_config(const struct device *dev, struct espi_cfg *cfg);
485
z_impl_espi_config(const struct device * dev,struct espi_cfg * cfg)486 static inline int z_impl_espi_config(const struct device *dev,
487 struct espi_cfg *cfg)
488 {
489 const struct espi_driver_api *api =
490 (const struct espi_driver_api *)dev->api;
491
492 return api->config(dev, cfg);
493 }
494
495 /**
496 * @brief Query to see if it a channel is ready.
497 *
498 * This routine allows to check if logical channel is ready before use.
499 * Note that queries for channels not supported will always return false.
500 *
501 * @param dev Pointer to the device structure for the driver instance.
502 * @param ch the eSPI channel for which status is to be retrieved.
503 *
504 * @retval true If eSPI channel is ready.
505 * @retval false otherwise.
506 */
507 __syscall bool espi_get_channel_status(const struct device *dev,
508 enum espi_channel ch);
509
z_impl_espi_get_channel_status(const struct device * dev,enum espi_channel ch)510 static inline bool z_impl_espi_get_channel_status(const struct device *dev,
511 enum espi_channel ch)
512 {
513 const struct espi_driver_api *api =
514 (const struct espi_driver_api *)dev->api;
515
516 return api->get_channel_status(dev, ch);
517 }
518
519 /**
520 * @brief Sends memory, I/O or message read request over eSPI.
521 *
522 * This routines provides a generic interface to send a read request packet.
523 *
524 * @param dev Pointer to the device structure for the driver instance.
525 * @param req Address of structure representing a memory,
526 * I/O or message read request.
527 *
528 * @retval 0 If successful.
529 * @retval -ENOTSUP if eSPI controller doesn't support raw packets and instead
530 * low memory transactions are handled by controller hardware directly.
531 * @retval -EIO General input / output error, failed to send over the bus.
532 */
533 __syscall int espi_read_request(const struct device *dev,
534 struct espi_request_packet *req);
535
z_impl_espi_read_request(const struct device * dev,struct espi_request_packet * req)536 static inline int z_impl_espi_read_request(const struct device *dev,
537 struct espi_request_packet *req)
538 {
539 const struct espi_driver_api *api =
540 (const struct espi_driver_api *)dev->api;
541
542 if (!api->read_request) {
543 return -ENOTSUP;
544 }
545
546 return api->read_request(dev, req);
547 }
548
549 /**
550 * @brief Sends memory, I/O or message write request over eSPI.
551 *
552 * This routines provides a generic interface to send a write request packet.
553 *
554 * @param dev Pointer to the device structure for the driver instance.
555 * @param req Address of structure representing a memory, I/O or
556 * message write request.
557 *
558 * @retval 0 If successful.
559 * @retval -ENOTSUP if eSPI controller doesn't support raw packets and instead
560 * low memory transactions are handled by controller hardware directly.
561 * @retval -EINVAL General input / output error, failed to send over the bus.
562 */
563 __syscall int espi_write_request(const struct device *dev,
564 struct espi_request_packet *req);
565
z_impl_espi_write_request(const struct device * dev,struct espi_request_packet * req)566 static inline int z_impl_espi_write_request(const struct device *dev,
567 struct espi_request_packet *req)
568 {
569 const struct espi_driver_api *api =
570 (const struct espi_driver_api *)dev->api;
571
572 if (!api->write_request) {
573 return -ENOTSUP;
574 }
575
576 return api->write_request(dev, req);
577 }
578
579 /**
580 * @brief Reads SOC data from a LPC peripheral with information
581 * updated over eSPI.
582 *
583 * This routine provides a generic interface to read a block whose
584 * information was updated by an eSPI transaction. Reading may trigger
585 * a transaction. The eSPI packet is assembled by the HW block.
586 *
587 * @param dev Pointer to the device structure for the driver instance.
588 * @param op Enum representing opcode for peripheral type and read request.
589 * @param data Parameter to be read from to the LPC peripheral.
590 *
591 * @retval 0 If successful.
592 * @retval -ENOTSUP if eSPI peripheral is off or not supported.
593 * @retval -EINVAL for unimplemented lpc opcode, but in range.
594 */
595 __syscall int espi_read_lpc_request(const struct device *dev,
596 enum lpc_peripheral_opcode op,
597 uint32_t *data);
598
z_impl_espi_read_lpc_request(const struct device * dev,enum lpc_peripheral_opcode op,uint32_t * data)599 static inline int z_impl_espi_read_lpc_request(const struct device *dev,
600 enum lpc_peripheral_opcode op,
601 uint32_t *data)
602 {
603 const struct espi_driver_api *api =
604 (const struct espi_driver_api *)dev->api;
605
606 if (!api->read_lpc_request) {
607 return -ENOTSUP;
608 }
609
610 return api->read_lpc_request(dev, op, data);
611 }
612
613 /**
614 * @brief Writes data to a LPC peripheral which generates an eSPI transaction.
615 *
616 * This routine provides a generic interface to write data to a block which
617 * triggers an eSPI transaction. The eSPI packet is assembled by the HW
618 * block.
619 *
620 * @param dev Pointer to the device structure for the driver instance.
621 * @param op Enum representing an opcode for peripheral type and write request.
622 * @param data Represents the parameter passed to the LPC peripheral.
623 *
624 * @retval 0 If successful.
625 * @retval -ENOTSUP if eSPI peripheral is off or not supported.
626 * @retval -EINVAL for unimplemented lpc opcode, but in range.
627 */
628 __syscall int espi_write_lpc_request(const struct device *dev,
629 enum lpc_peripheral_opcode op,
630 uint32_t *data);
631
z_impl_espi_write_lpc_request(const struct device * dev,enum lpc_peripheral_opcode op,uint32_t * data)632 static inline int z_impl_espi_write_lpc_request(const struct device *dev,
633 enum lpc_peripheral_opcode op,
634 uint32_t *data)
635 {
636 const struct espi_driver_api *api =
637 (const struct espi_driver_api *)dev->api;
638
639 if (!api->write_lpc_request) {
640 return -ENOTSUP;
641 }
642
643 return api->write_lpc_request(dev, op, data);
644 }
645
646 /**
647 * @brief Sends system/platform signal as a virtual wire packet.
648 *
649 * This routines provides a generic interface to send a virtual wire packet
650 * from slave to master.
651 *
652 * @param dev Pointer to the device structure for the driver instance.
653 * @param signal The signal to be send to eSPI master.
654 * @param level The level of signal requested LOW or HIGH.
655 *
656 * @retval 0 If successful.
657 * @retval -EIO General input / output error, failed to send over the bus.
658 */
659 __syscall int espi_send_vwire(const struct device *dev,
660 enum espi_vwire_signal signal,
661 uint8_t level);
662
z_impl_espi_send_vwire(const struct device * dev,enum espi_vwire_signal signal,uint8_t level)663 static inline int z_impl_espi_send_vwire(const struct device *dev,
664 enum espi_vwire_signal signal,
665 uint8_t level)
666 {
667 const struct espi_driver_api *api =
668 (const struct espi_driver_api *)dev->api;
669
670 return api->send_vwire(dev, signal, level);
671 }
672
673 /**
674 * @brief Retrieves level status for a signal encapsulated in a virtual wire.
675 *
676 * This routines provides a generic interface to request a virtual wire packet
677 * from eSPI master and retrieve the signal level.
678 *
679 * @param dev Pointer to the device structure for the driver instance.
680 * @param signal the signal to be requested from eSPI master.
681 * @param level the level of signal requested 0b LOW, 1b HIGH.
682 *
683 * @retval -EIO General input / output error, failed request to master.
684 */
685 __syscall int espi_receive_vwire(const struct device *dev,
686 enum espi_vwire_signal signal,
687 uint8_t *level);
688
z_impl_espi_receive_vwire(const struct device * dev,enum espi_vwire_signal signal,uint8_t * level)689 static inline int z_impl_espi_receive_vwire(const struct device *dev,
690 enum espi_vwire_signal signal,
691 uint8_t *level)
692 {
693 const struct espi_driver_api *api =
694 (const struct espi_driver_api *)dev->api;
695
696 return api->receive_vwire(dev, signal, level);
697 }
698
699 /**
700 * @brief Sends SMBus transaction (out-of-band) packet over eSPI bus.
701 *
702 * This routines provides an interface to encapsulate a SMBus transaction
703 * and send into packet over eSPI bus
704 *
705 * @param dev Pointer to the device structure for the driver instance.
706 * @param pckt Address of the packet representation of SMBus transaction.
707 *
708 * @retval -EIO General input / output error, failed request to master.
709 */
710 __syscall int espi_send_oob(const struct device *dev,
711 struct espi_oob_packet *pckt);
712
z_impl_espi_send_oob(const struct device * dev,struct espi_oob_packet * pckt)713 static inline int z_impl_espi_send_oob(const struct device *dev,
714 struct espi_oob_packet *pckt)
715 {
716 const struct espi_driver_api *api =
717 (const struct espi_driver_api *)dev->api;
718
719 if (!api->send_oob) {
720 return -ENOTSUP;
721 }
722
723 return api->send_oob(dev, pckt);
724 }
725
726 /**
727 * @brief Receives SMBus transaction (out-of-band) packet from eSPI bus.
728 *
729 * This routines provides an interface to receive and decoded a SMBus
730 * transaction from eSPI bus
731 *
732 * @param dev Pointer to the device structure for the driver instance.
733 * @param pckt Address of the packet representation of SMBus transaction.
734 *
735 * @retval -EIO General input / output error, failed request to master.
736 */
737 __syscall int espi_receive_oob(const struct device *dev,
738 struct espi_oob_packet *pckt);
739
z_impl_espi_receive_oob(const struct device * dev,struct espi_oob_packet * pckt)740 static inline int z_impl_espi_receive_oob(const struct device *dev,
741 struct espi_oob_packet *pckt)
742 {
743 const struct espi_driver_api *api =
744 (const struct espi_driver_api *)dev->api;
745
746 if (!api->receive_oob) {
747 return -ENOTSUP;
748 }
749
750 return api->receive_oob(dev, pckt);
751 }
752
753 /**
754 * @brief Sends a read request packet for shared flash.
755 *
756 * This routines provides an interface to send a request to read the flash
757 * component shared between the eSPI master and eSPI slaves.
758 *
759 * @param dev Pointer to the device structure for the driver instance.
760 * @param pckt Adddress of the representation of read flash transaction.
761 *
762 * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
763 * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
764 * @retval -EIO General input / output error, failed request to master.
765 */
766 __syscall int espi_read_flash(const struct device *dev,
767 struct espi_flash_packet *pckt);
768
z_impl_espi_read_flash(const struct device * dev,struct espi_flash_packet * pckt)769 static inline int z_impl_espi_read_flash(const struct device *dev,
770 struct espi_flash_packet *pckt)
771 {
772 const struct espi_driver_api *api =
773 (const struct espi_driver_api *)dev->api;
774
775 if (!api->flash_read) {
776 return -ENOTSUP;
777 }
778
779 return api->flash_read(dev, pckt);
780 }
781
782 /**
783 * @brief Sends a write request packet for shared flash.
784 *
785 * This routines provides an interface to send a request to write to the flash
786 * components shared between the eSPI master and eSPI slaves.
787 *
788 * @param dev Pointer to the device structure for the driver instance.
789 * @param pckt Address of the representation of write flash transaction.
790 *
791 * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
792 * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
793 * @retval -EIO General input / output error, failed request to master.
794 */
795 __syscall int espi_write_flash(const struct device *dev,
796 struct espi_flash_packet *pckt);
797
z_impl_espi_write_flash(const struct device * dev,struct espi_flash_packet * pckt)798 static inline int z_impl_espi_write_flash(const struct device *dev,
799 struct espi_flash_packet *pckt)
800 {
801 const struct espi_driver_api *api =
802 (const struct espi_driver_api *)dev->api;
803
804 if (!api->flash_write) {
805 return -ENOTSUP;
806 }
807
808 return api->flash_write(dev, pckt);
809 }
810
811 /**
812 * @brief Sends a write request packet for shared flash.
813 *
814 * This routines provides an interface to send a request to write to the flash
815 * components shared between the eSPI master and eSPI slaves.
816 *
817 * @param dev Pointer to the device structure for the driver instance.
818 * @param pckt Address of the representation of write flash transaction.
819 *
820 * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
821 * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
822 * @retval -EIO General input / output error, failed request to master.
823 */
824 __syscall int espi_flash_erase(const struct device *dev,
825 struct espi_flash_packet *pckt);
826
z_impl_espi_flash_erase(const struct device * dev,struct espi_flash_packet * pckt)827 static inline int z_impl_espi_flash_erase(const struct device *dev,
828 struct espi_flash_packet *pckt)
829 {
830 const struct espi_driver_api *api =
831 (const struct espi_driver_api *)dev->api;
832
833 if (!api->flash_erase) {
834 return -ENOTSUP;
835 }
836
837 return api->flash_erase(dev, pckt);
838 }
839
840 /**
841 * Callback model
842 *
843 *+-------+ +-------------+ +------+ +---------+
844 *| App | | eSPI driver | | HW | |eSPI Host|
845 *+---+---+ +-------+-----+ +---+--+ +----+----+
846 * | | | |
847 * | espi_init_callback | | |
848 * +----------------------------> | | |
849 * | espi_add_callback | |
850 * +----------------------------->+ |
851 * | | | eSPI reset | eSPI host
852 * | | IRQ +<------------+ resets the
853 * | | <-----------+ | bus
854 * | | | |
855 * | | Processed | |
856 * | | within the | |
857 * | | driver | |
858 * | | | |
859
860 * | | | VW CH ready| eSPI host
861 * | | IRQ +<------------+ enables VW
862 * | | <-----------+ | channel
863 * | | | |
864 * | | Processed | |
865 * | | within the | |
866 * | | driver | |
867 * | | | |
868 * | | | Memory I/O | Peripheral
869 * | | <-------------+ event
870 * | +<------------+ |
871 * +<-----------------------------+ callback | |
872 * | Report peripheral event | | |
873 * | and data for the event | | |
874 * | | | |
875 * | | | SLP_S5 | eSPI host
876 * | | <-------------+ send VWire
877 * | +<------------+ |
878 * +<-----------------------------+ callback | |
879 * | App enables/configures | | |
880 * | discrete regulator | | |
881 * | | | |
882 * | espi_send_vwire_signal | | |
883 * +------------------------------>------------>|------------>|
884 * | | | |
885 * | | | HOST_RST | eSPI host
886 * | | <-------------+ send VWire
887 * | +<------------+ |
888 * +<-----------------------------+ callback | |
889 * | App reset host-related | | |
890 * | data structures | | |
891 * | | | |
892 * | | | C10 | eSPI host
893 * | | +<------------+ send VWire
894 * | <-------------+ |
895 * <------------------------------+ | |
896 * | App executes | | |
897 * + power mgmt policy | | |
898 */
899
900 /**
901 * @brief Helper to initialize a struct espi_callback properly.
902 *
903 * @param callback A valid Application's callback structure pointer.
904 * @param handler A valid handler function pointer.
905 * @param evt_type indicates the eSPI event relevant for the handler.
906 * for VWIRE_RECEIVED event the data will indicate the new level asserted
907 */
espi_init_callback(struct espi_callback * callback,espi_callback_handler_t handler,enum espi_bus_event evt_type)908 static inline void espi_init_callback(struct espi_callback *callback,
909 espi_callback_handler_t handler,
910 enum espi_bus_event evt_type)
911 {
912 __ASSERT(callback, "Callback pointer should not be NULL");
913 __ASSERT(handler, "Callback handler pointer should not be NULL");
914
915 callback->handler = handler;
916 callback->evt_type = evt_type;
917 }
918
919 /**
920 * @brief Add an application callback.
921 * @param dev Pointer to the device structure for the driver instance.
922 * @param callback A valid Application's callback structure pointer.
923 * @return 0 if successful, negative errno code on failure.
924 *
925 * @note Callbacks may be added to the device from within a callback
926 * handler invocation, but whether they are invoked for the current
927 * eSPI event is not specified.
928 *
929 * Note: enables to add as many callback as needed on the same device.
930 */
espi_add_callback(const struct device * dev,struct espi_callback * callback)931 static inline int espi_add_callback(const struct device *dev,
932 struct espi_callback *callback)
933 {
934 const struct espi_driver_api *api =
935 (const struct espi_driver_api *)dev->api;
936
937 if (!api->manage_callback) {
938 return -ENOTSUP;
939 }
940
941 return api->manage_callback(dev, callback, true);
942 }
943
944 /**
945 * @brief Remove an application callback.
946 * @param dev Pointer to the device structure for the driver instance.
947 * @param callback A valid application's callback structure pointer.
948 * @return 0 if successful, negative errno code on failure.
949 *
950 * @warning It is explicitly permitted, within a callback handler, to
951 * remove the registration for the callback that is running, i.e. @p
952 * callback. Attempts to remove other registrations on the same
953 * device may result in undefined behavior, including failure to
954 * invoke callbacks that remain registered and unintended invocation
955 * of removed callbacks.
956 *
957 * Note: enables to remove as many callbacks as added through
958 * espi_add_callback().
959 */
espi_remove_callback(const struct device * dev,struct espi_callback * callback)960 static inline int espi_remove_callback(const struct device *dev,
961 struct espi_callback *callback)
962 {
963 const struct espi_driver_api *api =
964 (const struct espi_driver_api *)dev->api;
965
966 if (!api->manage_callback) {
967 return -ENOTSUP;
968 }
969
970 return api->manage_callback(dev, callback, false);
971 }
972
973 #ifdef __cplusplus
974 }
975 #endif
976
977 /**
978 * @}
979 */
980 #include <syscalls/espi.h>
981 #endif /* ZEPHYR_INCLUDE_ESPI_H_ */
982