summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2023-03-30 10:22:52 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-03-31 22:05:47 +0000
commit05c272ecc43d85af2515cbc863eaf81503658924 (patch)
tree984577378b0df983ab69a64d85bb2a2c106c2e18
parent9ba8369296711de6e470265a04b2b4c083908b9d (diff)
downloadchrome-ec-05c272ecc43d85af2515cbc863eaf81503658924.tar.gz
Zephyr test: Add ISL9241 emulator
Add an emulator for the ISL9241 charger chip. BRANCH=None BUG=b:273722902 TEST=builds Change-Id: I1d8ea900188ca3868d09df7620d172403a94e926 Signed-off-by: Diana Z <dzigterman@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4387136 Reviewed-by: Aaron Massey <aaronmassey@google.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--zephyr/emul/CMakeLists.txt1
-rw-r--r--zephyr/emul/Kconfig10
-rw-r--r--zephyr/emul/emul_isl9241.c182
-rw-r--r--zephyr/include/emul/emul_isl9241.h36
4 files changed, 229 insertions, 0 deletions
diff --git a/zephyr/emul/CMakeLists.txt b/zephyr/emul/CMakeLists.txt
index 77a8de3213..b9025e97d8 100644
--- a/zephyr/emul/CMakeLists.txt
+++ b/zephyr/emul/CMakeLists.txt
@@ -18,6 +18,7 @@ zephyr_library_sources_ifdef(CONFIG_EMUL_CLOCK_CONTROL emul_clock_control.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_COMMON_I2C emul_common_i2c.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_CROS_FLASH emul_flash.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_ISL923X emul_isl923x.c)
+zephyr_library_sources_ifdef(CONFIG_EMUL_CHARGER_ISL9241 emul_isl9241.c)
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)
diff --git a/zephyr/emul/Kconfig b/zephyr/emul/Kconfig
index b7bfc88aa2..700e0c0eaf 100644
--- a/zephyr/emul/Kconfig
+++ b/zephyr/emul/Kconfig
@@ -49,6 +49,16 @@ config EMUL_BC12_DETECT_PI3USB9201
detector/advertiser. The emulator supports reading and writing the
4 I2C registers of the PI3USB9201 using the emulated I2C bus.
+config EMUL_CHARGER_ISL9241
+ bool "Renesas buck-boost battery charger emulator"
+ default y
+ depends on ZTEST && DT_HAS_INTERSIL_ISL9241_ENABLED
+ select EMUL_COMMON_I2C
+ help
+ Enable the ISL9241 emulator. This chip is a configurable buck-boost
+ battery charger which can communicate over I2C, and utilizes the
+ emulated I2C bus.
+
config EMUL_PPC_SYV682X
bool "Silergy SYV682x PPC emulator"
default y
diff --git a/zephyr/emul/emul_isl9241.c b/zephyr/emul/emul_isl9241.c
new file mode 100644
index 0000000000..2b41230e5b
--- /dev/null
+++ b/zephyr/emul/emul_isl9241.c
@@ -0,0 +1,182 @@
+/* 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 "charger/chg_isl9241.h"
+#include "driver/charger/isl9241.h"
+#include "emul/emul_common_i2c.h"
+#include "emul/emul_stub_device.h"
+#include "util.h"
+
+#include <zephyr/device.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/ztest.h>
+
+#define DT_DRV_COMPAT ISL9241_CHG_COMPAT
+
+#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
+LOG_MODULE_REGISTER(emul_isl9241);
+
+/* Device ID sits at the end of the register space (0xFF) */
+#define ISL9241_MAX_REG ISL9241_REG_DEVICE_ID
+
+struct isl9241_emul_data {
+ struct i2c_common_emul_data common;
+ uint16_t regs[ISL9241_MAX_REG + 1];
+};
+
+/* Note: registers are all 2 bytes */
+struct isl9241_reg_default {
+ uint8_t offset;
+ uint16_t val;
+};
+
+/* Chip defaults for non-zero registers (spec Rev 5.0, Table 1) */
+struct isl9241_reg_default isl9241_defaults[] = {
+ /* Note: 3s default here */
+ { .offset = ISL9241_REG_MAX_SYSTEM_VOLTAGE, .val = 0x3120 },
+ { .offset = ISL9241_REG_ADAPTER_CUR_LIMIT2, .val = 0x05DC },
+ { .offset = ISL9241_REG_CONTROL1, .val = 0x0103 },
+ { .offset = ISL9241_REG_CONTROL2, .val = 0x6000 },
+ { .offset = ISL9241_REG_ADAPTER_CUR_LIMIT1, .val = 0x05DC },
+ { .offset = ISL9241_REG_CONTROL6, .val = 0x1FFF },
+ { .offset = ISL9241_REG_AC_PROCHOT, .val = 0x0C00 },
+ { .offset = ISL9241_REG_DC_PROCHOT, .val = 0x1000 },
+ { .offset = ISL9241_REG_OTG_VOLTAGE, .val = 0x0D08 },
+ { .offset = ISL9241_REG_OTG_CURRENT, .val = 0x0200 },
+ { .offset = ISL9241_REG_VIN_VOLTAGE, .val = 0x0C00 },
+ { .offset = ISL9241_REG_CONTROL3, .val = 0x0300 },
+ { .offset = ISL9241_REG_MANUFACTURER_ID, .val = 0x0049 },
+ { .offset = ISL9241_REG_DEVICE_ID, .val = 0x000E },
+};
+
+void isl9241_emul_reset_regs(const struct emul *emul)
+{
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+
+ memset(data->regs, 0, sizeof(data->regs));
+
+ for (int i = 0; i < ARRAY_SIZE(isl9241_defaults); i++) {
+ struct isl9241_reg_default def = isl9241_defaults[i];
+
+ data->regs[def.offset] = def.val;
+ }
+}
+
+uint16_t isl9241_emul_peek(const struct emul *emul, int reg)
+{
+ __ASSERT_NO_MSG(IN_RANGE(reg, 0, ISL9241_MAX_REG));
+
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+
+ return data->regs[reg];
+}
+
+void isl9241_emul_set_vbus(const struct emul *emul, int vbus_mv)
+{
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+ uint16_t adc_reg;
+
+ if (vbus_mv > 0)
+ data->regs[ISL9241_REG_INFORMATION2] |=
+ ISL9241_INFORMATION2_ACOK_PIN;
+ else
+ data->regs[ISL9241_REG_INFORMATION2] &=
+ ~ISL9241_INFORMATION2_ACOK_PIN;
+
+ adc_reg = vbus_mv / ISL9241_VIN_ADC_STEP_MV;
+ adc_reg <<= ISL9241_VIN_ADC_BIT_OFFSET;
+ data->regs[ISL9241_REG_VIN_ADC_RESULTS] = adc_reg;
+}
+
+void isl9241_emul_set_vsys(const struct emul *emul, int vsys_mv)
+{
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+ uint16_t adc_reg;
+
+ adc_reg = vsys_mv / ISL9241_VIN_ADC_STEP_MV;
+ adc_reg <<= ISL9241_VIN_ADC_BIT_OFFSET;
+ data->regs[ISL9241_REG_VSYS_ADC_RESULTS] = adc_reg;
+}
+
+static int isl9241_emul_read(const struct emul *emul, int reg, uint8_t *val,
+ int bytes, void *unused_data)
+{
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+
+ if (!IN_RANGE(reg, 0, ISL9241_MAX_REG))
+ return -EINVAL;
+
+ if (!IN_RANGE(bytes, 0, 1))
+ return -EINVAL;
+
+ if (bytes == 0)
+ *val = (uint8_t)(data->regs[reg] & 0xFF);
+ else
+ *val = (uint8_t)((data->regs[reg] >> 8) & 0xFF);
+
+ return 0;
+}
+
+static int isl9241_emul_write(const struct emul *emul, int reg, uint8_t val,
+ int bytes, void *unused_data)
+{
+ struct isl9241_emul_data *data = (struct isl9241_emul_data *)emul->data;
+
+ if (!IN_RANGE(reg, 0, ISL9241_MAX_REG))
+ return -EINVAL;
+
+ if (!IN_RANGE(bytes, 1, 2))
+ return -EINVAL;
+
+ if (bytes == 1)
+ data->regs[reg] = val & 0xFF;
+ else
+ data->regs[reg] |= val << 8;
+
+ return 0;
+}
+
+static int isl9241_emul_init(const struct emul *emul,
+ const struct device *parent)
+{
+ struct isl9241_emul_data *data = (struct isl9241_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, isl9241_emul_read, NULL);
+ i2c_common_emul_set_write_func(common_data, isl9241_emul_write, NULL);
+
+ isl9241_emul_reset_regs(emul);
+
+ return 0;
+}
+
+#define INIT_ISL9241_EMUL(n) \
+ static struct i2c_common_emul_cfg common_cfg_##n; \
+ static struct isl9241_emul_data isl9241_emul_data_##n; \
+ static struct i2c_common_emul_cfg common_cfg_##n = { \
+ .dev_label = DT_NODE_FULL_NAME(DT_DRV_INST(n)), \
+ .data = &isl9241_emul_data_##n.common, \
+ .addr = DT_INST_REG_ADDR(n) \
+ }; \
+ EMUL_DT_INST_DEFINE(n, isl9241_emul_init, &isl9241_emul_data_##n, \
+ &common_cfg_##n, &i2c_common_emul_api, NULL)
+
+DT_INST_FOREACH_STATUS_OKAY(INIT_ISL9241_EMUL)
+
+DT_INST_FOREACH_STATUS_OKAY(EMUL_STUB_DEVICE);
+
+static void isl9241_emul_reset_rule_before(const struct ztest_unit_test *test,
+ void *data)
+{
+ ARG_UNUSED(test);
+ ARG_UNUSED(data);
+
+#define ISL9241_EMUL_RESET_RULE_BEFORE(n) \
+ isl9241_emul_reset_regs(EMUL_DT_GET(DT_DRV_INST(n)))
+
+ DT_INST_FOREACH_STATUS_OKAY(ISL9241_EMUL_RESET_RULE_BEFORE);
+}
+ZTEST_RULE(isl9241_emul_reset, isl9241_emul_reset_rule_before, NULL);
diff --git a/zephyr/include/emul/emul_isl9241.h b/zephyr/include/emul/emul_isl9241.h
new file mode 100644
index 0000000000..2838687731
--- /dev/null
+++ b/zephyr/include/emul/emul_isl9241.h
@@ -0,0 +1,36 @@
+/* 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_ISL9241_H
+#define EMUL_ISL9241_H
+
+#include <zephyr/drivers/emul.h>
+
+/**
+ * Peek an internal register value
+ *
+ * @param emul - ISL9241 emulator data
+ * @param reg - which register to peek
+ * @return register contents
+ */
+uint16_t isl9241_emul_peek(const struct emul *emul, int reg);
+
+/**
+ * Fake a Vbus voltage presence
+ *
+ * @param emul - ISL9241 emulator data
+ * @param vbus_mv - desired Vbus mV to set
+ */
+void isl9241_emul_set_vbus(const struct emul *emul, int vbus_mv);
+
+/**
+ * Fake a specific Vsys voltage
+ *
+ * @param emul - ISL9241 emulator data
+ * @param vsys_mv - desired Vsys mV to set
+ */
+void isl9241_emul_set_vsys(const struct emul *emul, int vsys_mv);
+
+#endif