summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2023-03-31 11:52:19 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-03 21:17:25 +0000
commit28aed31368f182211278cae7f0d93625ce62be77 (patch)
tree3cc7e1943bce84c1e45fa5cd981cf691469f5dde
parent5a655201cd33da08e5956f29e3315381b3c1bfaa (diff)
downloadchrome-ec-28aed31368f182211278cae7f0d93625ce62be77.tar.gz
Zephyr test: Create NX20P383X emulator
Create an emulator for this PPC so tests may use it as an available i2c target. BRANCH=None BUG=b:276468569 TEST=./twister -T ./zephyr/test LOW_COVERAGE_REASON=emulator edge cases not tested Change-Id: I54b8aced582e81b3f61895f25b472bce79dddc50 Signed-off-by: Diana Z <dzigterman@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4389617 Reviewed-by: Keith Short <keithshort@chromium.org> Commit-Queue: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/emul/CMakeLists.txt1
-rw-r--r--zephyr/emul/Kconfig10
-rw-r--r--zephyr/emul/emul_nx20p348x.c157
-rw-r--r--zephyr/include/emul/emul_nx20p348x.h20
-rw-r--r--zephyr/test/drivers/usbc_ppc/ppc_alts.dts2
5 files changed, 189 insertions, 1 deletions
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt
index b9025e97d8..523e1e98b0 100644
--- a/zephyr/emul/CMakeLists.txt
+++ b/zephyr/emul/CMakeLists.txt
@@ -23,6 +23,7 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_KB_RAW emul_kb_raw.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_LIS2DW12 emul_lis2dw12.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_LN9310 emul_ln9310.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_PCT2075 emul_pct2075.c)
+zephyr_library_sources_ifdef(CONFIG_EMUL_PPC_NX20P348X emul_nx20p348x.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_PPC_SYV682X emul_syv682x.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_PS8743 emul_ps8743.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_RT9490 emul_rt9490.c)
diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig
index 700e0c0eaf..b160e430b2 100644
--- a/zephyr/emul/Kconfig
+++ b/zephyr/emul/Kconfig
@@ -59,6 +59,16 @@ config EMUL_CHARGER_ISL9241
battery charger which can communicate over I2C, and utilizes the
emulated I2C bus.
+config EMUL_PPC_NX20P348X
+ bool "NXP PPC emulator"
+ default y
+ depends on ZTEST && DT_HAS_NXP_NX20P348X_ENABLED
+ select EMUL_COMMON_I2C
+ help
+ Enable the NX20P348X emulator, which covers both the NX20P3481 and
+ NX20P3483. It is also register compatible with the SM5360A. This
+ emulator makes use of the emulated I2C bus.
+
config EMUL_PPC_SYV682X
bool "Silergy SYV682x PPC emulator"
default y
diff --git a/zephyr/emul/emul_nx20p348x.c b/zephyr/emul/emul_nx20p348x.c
new file mode 100644
index 0000000000..a483295a69
--- /dev/null
+++ b/zephyr/emul/emul_nx20p348x.c
@@ -0,0 +1,157 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "driver/ppc/nx20p348x.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_stub_device.h"
+#include "usbc/ppc_nx20p348x.h"
+#include "usbc_ppc.h"
+#include "util.h"
+
+#include <zephyr/device.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/ztest.h>
+
+#define DT_DRV_COMPAT NX20P348X_COMPAT
+
+#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
+LOG_MODULE_REGISTER(emul_nx20p348x);
+
+/*
+ * Device control reg marks the end of defined regs for the NX20P3483 (0x0B)
+ */
+#define NX20P348X_MAX_REG NX20P348X_DEVICE_CONTROL_REG
+
+struct nx20p348x_emul_data {
+ struct i2c_common_emul_data common;
+ uint8_t regs[NX20P348X_MAX_REG + 1];
+};
+
+struct nx20p348x_reg_default {
+ uint8_t offset;
+ uint8_t val;
+};
+
+/* Chip defaults for non-zero registers (spec Rev 0.4 Table 9) */
+struct nx20p348x_reg_default nx20p348x_defaults[] = {
+ { .offset = NX20P348X_DEVICE_ID_REG, .val = 0x09 },
+ { .offset = NX20P348X_OVLO_THRESHOLD_REG, .val = 0x01 },
+ { .offset = NX20P348X_HV_SRC_OCP_THRESHOLD_REG, .val = 0x0B },
+ { .offset = NX20P348X_5V_SRC_OCP_THRESHOLD_REG, .val = 0x0B },
+};
+
+void nx20p348x_emul_reset_regs(const struct emul *emul)
+{
+ struct nx20p348x_emul_data *data =
+ (struct nx20p348x_emul_data *)emul->data;
+
+ memset(data->regs, 0, sizeof(data->regs));
+
+ for (int i = 0; i < ARRAY_SIZE(nx20p348x_defaults); i++) {
+ struct nx20p348x_reg_default def = nx20p348x_defaults[i];
+
+ data->regs[def.offset] = def.val;
+ }
+}
+
+uint8_t nx20p348x_emul_peek(const struct emul *emul, int reg)
+{
+ __ASSERT_NO_MSG(IN_RANGE(reg, 0, NX20P348X_MAX_REG));
+
+ struct nx20p348x_emul_data *data =
+ (struct nx20p348x_emul_data *)emul->data;
+
+ return data->regs[reg];
+}
+
+static int nx20p348x_emul_read(const struct emul *emul, int reg, uint8_t *val,
+ int bytes, void *unused_data)
+{
+ struct nx20p348x_emul_data *data =
+ (struct nx20p348x_emul_data *)emul->data;
+
+ if (!IN_RANGE(reg, 0, NX20P348X_MAX_REG)) {
+ LOG_ERR("Register out of range: %d", reg);
+ return -EINVAL;
+ }
+
+ if (bytes != 0) {
+ LOG_ERR("Emulator expects single byte transactions: "
+ "%d bytes requested",
+ bytes);
+ return -EINVAL;
+ }
+
+ *val = data->regs[reg];
+
+ return 0;
+}
+
+static int nx20p348x_emul_write(const struct emul *emul, int reg, uint8_t val,
+ int bytes, void *unused_data)
+{
+ struct nx20p348x_emul_data *data =
+ (struct nx20p348x_emul_data *)emul->data;
+
+ if (!IN_RANGE(reg, 0, NX20P348X_MAX_REG)) {
+ LOG_ERR("Register out of range: %d", reg);
+ return -EINVAL;
+ }
+
+ if (bytes != 1) {
+ LOG_ERR("Emulator expects single byte transactions: "
+ "%d bytes written",
+ bytes);
+ return -EINVAL;
+ }
+
+ data->regs[reg] = val;
+
+ return 0;
+}
+
+static int nx20p348x_emul_init(const struct emul *emul,
+ const struct device *parent)
+{
+ struct nx20p348x_emul_data *data =
+ (struct nx20p348x_emul_data *)emul->data;
+ struct i2c_common_emul_data *common_data = &data->common;
+
+ i2c_common_emul_init(common_data);
+ i2c_common_emul_set_read_func(common_data, nx20p348x_emul_read, NULL);
+ i2c_common_emul_set_write_func(common_data, nx20p348x_emul_write, NULL);
+
+ nx20p348x_emul_reset_regs(emul);
+
+ return 0;
+}
+
+#define INIT_NX20P348X_EMUL(n) \
+ static struct i2c_common_emul_cfg common_cfg_##n; \
+ static struct nx20p348x_emul_data nx20p348x_emul_data_##n; \
+ static struct i2c_common_emul_cfg common_cfg_##n = { \
+ .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \
+ .data = &nx20p348x_emul_data_##n.common, \
+ .addr = DT_INST_REG_ADDR(n) \
+ }; \
+ EMUL_DT_INST_DEFINE(n, nx20p348x_emul_init, &nx20p348x_emul_data_##n, \
+ &common_cfg_##n, &i2c_common_emul_api, NULL)
+
+DT_INST_FOREACH_STATUS_OKAY(INIT_NX20P348X_EMUL)
+
+DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE);
+
+static void nx20p348x_emul_reset_rule_before(const struct ztest_unit_test *test,
+ void *data)
+{
+ ARG_UNUSED(test);
+ ARG_UNUSED(data);
+
+#define NX20P348X_EMUL_RESET_RULE_BEFORE(n) \
+ nx20p348x_emul_reset_regs(EMUL_DT_GET(DT_DRV_INST(n)))
+
+ DT_INST_FOREACH_STATUS_OKAY(NX20P348X_EMUL_RESET_RULE_BEFORE);
+}
+ZTEST_RULE(nx20p348x_emul_reset, nx20p348x_emul_reset_rule_before, NULL);
diff --git a/zephyr/include/emul/emul_nx20p348x.h b/zephyr/include/emul/emul_nx20p348x.h
new file mode 100644
index 0000000000..74e0041230
--- /dev/null
+++ b/zephyr/include/emul/emul_nx20p348x.h
@@ -0,0 +1,20 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef EMUL_NX20P348X_H
+#define EMUL_NX20P348X_H
+
+#include <zephyr/drivers/emul.h>
+
+/**
+ * Peek an internal register value
+ *
+ * @param emul - NX20P383X emulator data
+ * @param reg - which register to peek
+ * @return register contents
+ */
+uint8_t nx20p348x_emul_peek(const struct emul *emul, int reg);
+
+#endif
diff --git a/zephyr/test/drivers/usbc_ppc/ppc_alts.dts b/zephyr/test/drivers/usbc_ppc/ppc_alts.dts
index 09488dc91e..d0978238c3 100644
--- a/zephyr/test/drivers/usbc_ppc/ppc_alts.dts
+++ b/zephyr/test/drivers/usbc_ppc/ppc_alts.dts
@@ -17,7 +17,7 @@
&i2c0 {
ppc_nx20p348x_alt: nx20p348x@77 {
- compatible = "nxp,nx20p348x", "cros,i2c-mock";
+ compatible = "nxp,nx20p348x";
status = "okay";
reg = <0x77>;
is-alt;