summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Peress <peress@google.com>2021-10-17 23:04:15 -0600
committerCommit Bot <commit-bot@chromium.org>2021-10-18 20:58:11 +0000
commit78f5a2e13645460cd313d6487903e709f0d1143e (patch)
tree9976cbf251d1db3ef6bce4114b91b558c0689179
parent9229397b613fadac32f025a1be7d6549b2cd6be9 (diff)
downloadchrome-ec-78f5a2e13645460cd313d6487903e709f0d1143e.tar.gz
zephyr: ppc: sn5s330: Add test for func_set1 retry loop
Add a basic test that ensures that the func_set1 register write is attempted at least one more time on an initial failure. BRANCH=none BUG=b:203364783 TEST=zmake configure --test zephyr/test/drivers Signed-off-by: Yuval Peress <peress@google.com> Change-Id: Ib06794de0af29fb44e4cb550c7b1ef3c2667af0e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3229005 Commit-Queue: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
-rw-r--r--zephyr/dts/bindings/emul/cros,sn5s330.yaml12
-rw-r--r--zephyr/emul/CMakeLists.txt1
-rw-r--r--zephyr/emul/Kconfig1
-rw-r--r--zephyr/emul/Kconfig.sn5s33022
-rw-r--r--zephyr/emul/emul_sn5s330.c128
-rw-r--r--zephyr/include/emul/emul_sn5s330.h30
-rw-r--r--zephyr/test/drivers/overlay.dts6
-rw-r--r--zephyr/test/drivers/src/main.c2
-rw-r--r--zephyr/test/drivers/src/ppc_sn5s330.c60
9 files changed, 262 insertions, 0 deletions
diff --git a/zephyr/dts/bindings/emul/cros,sn5s330.yaml b/zephyr/dts/bindings/emul/cros,sn5s330.yaml
new file mode 100644
index 0000000000..b7964b777b
--- /dev/null
+++ b/zephyr/dts/bindings/emul/cros,sn5s330.yaml
@@ -0,0 +1,12 @@
+# Copyright 2021 The chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description: sn5s330 emulator
+
+compatible: "cros,sn5s330"
+
+include: base.yaml
+properties:
+ reg:
+ required: true
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt
index 19dcc84d30..ce3ad191eb 100644
--- a/zephyr/emul/CMakeLists.txt
+++ b/zephyr/emul/CMakeLists.txt
@@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_I2C_MOCK i2c_mock.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_ISL923X emul_isl923x.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_CLOCK_CONTROL emul_clock_control.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_TCPCI emul_tcpci.c)
+zephyr_library_sources_ifdef(CONFIG_EMUL_SN5S330 emul_sn5s330.c)
diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig
index 9a0b434bc9..a6b39405c6 100644
--- a/zephyr/emul/Kconfig
+++ b/zephyr/emul/Kconfig
@@ -73,3 +73,4 @@ rsource "Kconfig.i2c_mock"
rsource "Kconfig.isl923x"
rsource "Kconfig.clock_control"
rsource "Kconfig.tcpci"
+rsource "Kconfig.sn5s330"
diff --git a/zephyr/emul/Kconfig.sn5s330 b/zephyr/emul/Kconfig.sn5s330
new file mode 100644
index 0000000000..aba3bb9028
--- /dev/null
+++ b/zephyr/emul/Kconfig.sn5s330
@@ -0,0 +1,22 @@
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+DT_COMPAT_SN5S330_EMUL := cros,sn5s330-emul
+
+menuconfig EMUL_SN5S330
+ bool "sn5s330 emulator"
+ default $(dt_compat_enabled,$(DT_COMPAT_SN5S330_EMUL))
+ depends on I2C_EMUL
+ help
+ Enable the sn5s330 emulator. This driver uses the emulated I2C bus. It
+ is used to test the sn5s330 driver. Emulator API is available in
+ zephyr/include/emul/emul_sn5s330.h
+
+if EMUL_SN5S330
+
+module = SN5S330_EMUL
+module-str = sn5s330_emul
+source "subsys/logging/Kconfig.template.log_config"
+
+endif # EMUL_SN5S330
diff --git a/zephyr/emul/emul_sn5s330.c b/zephyr/emul/emul_sn5s330.c
new file mode 100644
index 0000000000..44334ec71b
--- /dev/null
+++ b/zephyr/emul/emul_sn5s330.c
@@ -0,0 +1,128 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#define DT_DRV_COMPAT cros_sn5s330_emul
+
+#include <device.h>
+#include <drivers/i2c.h>
+#include <drivers/i2c_emul.h>
+#include <emul.h>
+#include <errno.h>
+#include <sys/__assert.h>
+
+#include "driver/ppc/sn5s330.h"
+#include "driver/ppc/sn5s330_public.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_sn5s330.h"
+#include "i2c.h"
+
+#include <logging/log.h>
+LOG_MODULE_REGISTER(sn5s330_emul, CONFIG_SN5S330_EMUL_LOG_LEVEL);
+
+#define SN5S330_DATA_FROM_I2C_EMUL(_emul) \
+ CONTAINER_OF(CONTAINER_OF(_emul, struct i2c_common_emul_data, emul), \
+ struct sn5s330_emul_data, common)
+
+struct sn5s330_emul_data {
+ /** Common I2C data */
+ struct i2c_common_emul_data common;
+ /** Emulated FUNC_SET1 register */
+ uint8_t func_set1_reg;
+};
+
+struct sn5s330_emul_cfg {
+ /** Common I2C config */
+ const struct i2c_common_emul_cfg common;
+};
+
+struct i2c_emul *sn5s330_emul_to_i2c_emul(const struct emul *emul)
+{
+ struct sn5s330_emul_data *data = emul->data;
+
+ return &(data->common.emul);
+}
+
+int sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint32_t *val)
+{
+ struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul);
+
+ switch (reg) {
+ case SN5S330_FUNC_SET1:
+ *val = data->func_set1_reg;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int sn5s330_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val,
+ int bytes)
+{
+ struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul);
+
+ switch (reg) {
+ case SN5S330_FUNC_SET1:
+ __ASSERT_NO_MSG(bytes == 0);
+ *val = data->func_set1_reg;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sn5s330_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val,
+ int bytes)
+{
+ struct sn5s330_emul_data *data = SN5S330_DATA_FROM_I2C_EMUL(emul);
+
+ switch (reg) {
+ case SN5S330_FUNC_SET1:
+ __ASSERT_NO_MSG(bytes == 1);
+ data->func_set1_reg = val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int emul_sn5s330_init(const struct emul *emul,
+ const struct device *parent)
+{
+ const struct sn5s330_emul_cfg *cfg = emul->cfg;
+ struct sn5s330_emul_data *data = emul->data;
+
+ data->common.emul.api = &i2c_common_emul_api;
+ data->common.emul.addr = cfg->common.addr;
+ data->common.emul.parent = emul;
+ data->common.i2c = parent;
+ data->common.cfg = &cfg->common;
+ i2c_common_emul_init(&data->common);
+
+ return i2c_emul_register(parent, emul->dev_label, &data->common.emul);
+}
+
+#define INIT_SN5S330(n) \
+ static struct sn5s330_emul_data sn5s330_emul_data_##n = { \
+ .common = { \
+ .write_byte = sn5s330_emul_write_byte, \
+ .read_byte = sn5s330_emul_read_byte, \
+ }, \
+ }; \
+ static struct sn5s330_emul_cfg sn5s330_emul_cfg_##n = { \
+ .common = { \
+ .i2c_label = DT_INST_BUS_LABEL(n), \
+ .dev_label = DT_INST_LABEL(n), \
+ .addr = DT_INST_REG_ADDR(n), \
+ }, \
+ }; \
+ EMUL_DEFINE(emul_sn5s330_init, DT_DRV_INST(n), &sn5s330_emul_cfg_##n, \
+ &sn5s330_emul_data_##n)
+
+DT_INST_FOREACH_STATUS_OKAY(INIT_SN5S330)
diff --git a/zephyr/include/emul/emul_sn5s330.h b/zephyr/include/emul/emul_sn5s330.h
new file mode 100644
index 0000000000..ad6d0f04c1
--- /dev/null
+++ b/zephyr/include/emul/emul_sn5s330.h
@@ -0,0 +1,30 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef ZEPHYR_INCLUDE_EMUL_EMUL_SN5S330_H_
+#define ZEPHYR_INCLUDE_EMUL_EMUL_SN5S330_H_
+
+#include <emul.h>
+#include <drivers/i2c_emul.h>
+
+/**
+ * @brief The i2c emulator pointer from the top level emul.
+ *
+ * @param emul The emulator to query
+ * @return Pointer to the i2c emulator struct
+ */
+struct i2c_emul *sn5s330_emul_to_i2c_emul(const struct emul *emul);
+
+/**
+ * @brief Get the register value without incurring any side-effects
+ *
+ * @param emul The emulator to query
+ * @param reg The register to read
+ * @param val Pointer to write the register value to
+ * @return 0 on success
+ */
+int sn5s330_emul_peek_reg(const struct emul *emul, uint32_t reg, uint32_t *val);
+
+#endif /* ZEPHYR_INCLUDE_EMUL_EMUL_SN5S330_H_ */
diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts
index d49973180d..96fc7de31a 100644
--- a/zephyr/test/drivers/overlay.dts
+++ b/zephyr/test/drivers/overlay.dts
@@ -520,6 +520,12 @@
label = "PI3USB9201_EMUL";
};
+ sn5s330_emul: sn5s330@40 {
+ compatible = "cros,sn5s330-emul";
+ reg = <0x40>;
+ label = "SN5S330_EMUL";
+ };
+
syv682x_emul: syv682x@41 {
compatible = "zephyr,syv682x-emul";
reg = <0x41>;
diff --git a/zephyr/test/drivers/src/main.c b/zephyr/test/drivers/src/main.c
index 64e49b7006..ee82140ca6 100644
--- a/zephyr/test/drivers/src/main.c
+++ b/zephyr/test/drivers/src/main.c
@@ -26,6 +26,7 @@ extern void test_suite_stm_mems_common(void);
extern void test_suite_isl923x(void);
extern void test_suite_usb_mux(void);
extern void test_suite_ppc_syv682c(void);
+extern void test_suite_ppc_sn5s330(void);
extern void test_suite_cros_cbi(void);
extern void test_suite_tcpci(void);
@@ -54,6 +55,7 @@ void test_main(void)
test_suite_stm_mems_common();
test_suite_isl923x();
test_suite_usb_mux();
+ test_suite_ppc_sn5s330();
test_suite_ppc_syv682c();
test_suite_cros_cbi();
test_suite_tcpci();
diff --git a/zephyr/test/drivers/src/ppc_sn5s330.c b/zephyr/test/drivers/src/ppc_sn5s330.c
new file mode 100644
index 0000000000..f38376072a
--- /dev/null
+++ b/zephyr/test/drivers/src/ppc_sn5s330.c
@@ -0,0 +1,60 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <device.h>
+#include <devicetree.h>
+#include <emul.h>
+#include <ztest.h>
+
+#include "driver/ppc/sn5s330.h"
+#include "driver/ppc/sn5s330_public.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_sn5s330.h"
+#include "usbc_ppc.h"
+
+/** This must match the index of the sn5s330 in ppc_chips[] */
+#define SN5S330_PORT 0
+#define EMUL emul_get_binding(DT_LABEL(DT_NODELABEL(sn5s330_emul)))
+
+static int fail_until_write_func(struct i2c_emul *emul, int reg, uint8_t val,
+ int bytes, void *data)
+{
+ uint32_t *count = data;
+
+ if (*count != 0) {
+ *count -= 1;
+ return -EIO;
+ }
+ return 0;
+}
+
+static void test_fail_once_func_set1(void)
+{
+ const struct emul *emul = EMUL;
+ struct i2c_emul *i2c_emul = sn5s330_emul_to_i2c_emul(emul);
+ uint32_t count = 1;
+ uint32_t func_set1_value;
+
+ i2c_common_emul_set_write_func(i2c_emul, fail_until_write_func, &count);
+ /*
+ * Call the init and ignore the return value, we're just checking that
+ * setting FUNC_SET1 retries at least once.
+ */
+ sn5s330_drv.init(SN5S330_PORT);
+ zassert_equal(count, 0, NULL);
+ zassert_ok(sn5s330_emul_peek_reg(emul, SN5S330_FUNC_SET1,
+ &func_set1_value),
+ NULL);
+ zassert_true((func_set1_value & SN5S330_ILIM_1_62) != 0, NULL);
+ i2c_common_emul_set_write_func(i2c_emul, NULL, NULL);
+}
+
+void test_suite_ppc_sn5s330(void)
+{
+ ztest_test_suite(
+ ppc_sn5s330,
+ ztest_unit_test(test_fail_once_func_set1));
+ ztest_run_test_suite(ppc_sn5s330);
+}