1 /*
2  * Copyright 2020 Google LLC
3  * Copyright (c) 2020 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define LOG_LEVEL CONFIG_EMUL_LOG_LEVEL
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(emul);
11 
12 #include <zephyr/device.h>
13 #include <zephyr/drivers/emul.h>
14 #include <zephyr/sys/iterable_sections.h>
15 #include <string.h>
16 
emul_get_binding(const char * name)17 const struct emul *emul_get_binding(const char *name)
18 {
19 	STRUCT_SECTION_FOREACH(emul, emul_it) {
20 		if (strcmp(emul_it->dev->name, name) == 0) {
21 			return emul_it;
22 		}
23 	}
24 
25 	return NULL;
26 }
27 
emul_init_for_bus(const struct device * dev)28 int emul_init_for_bus(const struct device *dev)
29 {
30 	const struct emul_list_for_bus *cfg = dev->config;
31 
32 	/*
33 	 * Walk the list of children, find the corresponding emulator and
34 	 * initialise it.
35 	 */
36 	const struct emul_link_for_bus *elp;
37 	const struct emul_link_for_bus *const end = cfg->children + cfg->num_children;
38 
39 	LOG_INF("Registering %d emulator(s) for %s", cfg->num_children, dev->name);
40 	for (elp = cfg->children; elp < end; elp++) {
41 		const struct emul *emul = emul_get_binding(elp->dev->name);
42 
43 		if (!emul) {
44 			LOG_WRN("Cannot find emulator for '%s'", elp->dev->name);
45 			continue;
46 		}
47 
48 		switch (emul->bus_type) {
49 		case EMUL_BUS_TYPE_I2C:
50 			emul->bus.i2c->target = emul;
51 			break;
52 		case EMUL_BUS_TYPE_ESPI:
53 			emul->bus.espi->target = emul;
54 			break;
55 		case EMUL_BUS_TYPE_SPI:
56 			emul->bus.spi->target = emul;
57 			break;
58 		case EMUL_BUS_TYPE_MSPI:
59 			emul->bus.mspi->target = emul;
60 			break;
61 		case EMUL_BUS_TYPE_UART:
62 			emul->bus.uart->target = emul;
63 			break;
64 		case EMUL_BUS_TYPE_NONE:
65 			break;
66 		}
67 		int rc = emul->init(emul, dev);
68 
69 		if (rc != 0) {
70 			LOG_WRN("Init %s emulator failed: %d",
71 				 elp->dev->name, rc);
72 		}
73 
74 		switch (emul->bus_type) {
75 #ifdef CONFIG_I2C_EMUL
76 		case EMUL_BUS_TYPE_I2C:
77 			rc = i2c_emul_register(dev, emul->bus.i2c);
78 			break;
79 #endif /* CONFIG_I2C_EMUL */
80 #ifdef CONFIG_ESPI_EMUL
81 		case EMUL_BUS_TYPE_ESPI:
82 			rc = espi_emul_register(dev, emul->bus.espi);
83 			break;
84 #endif /* CONFIG_ESPI_EMUL */
85 #ifdef CONFIG_SPI_EMUL
86 		case EMUL_BUS_TYPE_SPI:
87 			rc = spi_emul_register(dev, emul->bus.spi);
88 			break;
89 #endif /* CONFIG_SPI_EMUL */
90 #ifdef CONFIG_MSPI_EMUL
91 		case EMUL_BUS_TYPE_MSPI:
92 			rc = mspi_emul_register(dev, emul->bus.mspi);
93 			break;
94 #endif /* CONFIG_MSPI_EMUL */
95 #ifdef CONFIG_UART_EMUL
96 		case EMUL_BUS_TYPE_UART:
97 			rc = uart_emul_register(dev, emul->bus.uart);
98 			break;
99 #endif /* CONFIG_UART_EMUL */
100 		default:
101 			rc = -EINVAL;
102 			LOG_WRN("Found no emulated bus enabled to register emulator %s",
103 				elp->dev->name);
104 		}
105 
106 		if (rc != 0) {
107 			LOG_WRN("Failed to register emulator for %s: %d", elp->dev->name, rc);
108 		}
109 	}
110 
111 	return 0;
112 }
113