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_NONE:
59 break;
60 }
61 int rc = emul->init(emul, dev);
62
63 if (rc != 0) {
64 LOG_WRN("Init %s emulator failed: %d",
65 elp->dev->name, rc);
66 }
67
68 switch (emul->bus_type) {
69 #ifdef CONFIG_I2C_EMUL
70 case EMUL_BUS_TYPE_I2C:
71 rc = i2c_emul_register(dev, emul->bus.i2c);
72 break;
73 #endif /* CONFIG_I2C_EMUL */
74 #ifdef CONFIG_ESPI_EMUL
75 case EMUL_BUS_TYPE_ESPI:
76 rc = espi_emul_register(dev, emul->bus.espi);
77 break;
78 #endif /* CONFIG_ESPI_EMUL */
79 #ifdef CONFIG_SPI_EMUL
80 case EMUL_BUS_TYPE_SPI:
81 rc = spi_emul_register(dev, emul->bus.spi);
82 break;
83 #endif /* CONFIG_SPI_EMUL */
84 default:
85 rc = -EINVAL;
86 LOG_WRN("Found no emulated bus enabled to register emulator %s",
87 elp->dev->name);
88 }
89
90 if (rc != 0) {
91 LOG_WRN("Failed to register emulator for %s: %d", elp->dev->name, rc);
92 }
93 }
94
95 return 0;
96 }
97